Python list of tuples, need to unpack and clean up

前端 未结 5 1866
一个人的身影
一个人的身影 2021-01-06 20:24

Assume you have a list such as

x = [(\'Edgar\',), (\'Robert\',)]

What would be the most efficient way to get to just the strings \'Edgar\

相关标签:
5条回答
  • 2021-01-06 20:39

    Here is one way:

    >>> [name for name, in x]
    ['Edgar', 'Robert']
    

    Note the placement of the comma, which unpacks the tuple.

    0 讨论(0)
  • 2021-01-06 20:43

    Easy solution, and the fastest in most cases.

    [item[0] for item in x]
    #or
    [item for (item,) in x]
    

    Alternatively if you need a functional interface to index access (but slightly slower):

    from operator import itemgetter
    
    zero_index = itemgetter(0)
    
    print map(zero_index, x)
    

    Finally, if your sequence is too small to fit in memory, you can do this iteratively. This is much slower on collections but uses only one item's worth of memory.

    from itertools import chain
    
    x = [('Edgar',), ('Robert',)]
    
    # list is to materialize the entire sequence.
    # Normally you would use this in a for loop with no `list()` call.
    print list(chain.from_iterable(x))
    

    But if all you are going to do is iterate anyway, you can also just use tuple unpacking:

    for (item,) in x:
        myfunc(item)
    
    0 讨论(0)
  • 2021-01-06 20:56
    >>> from operator import itemgetter
    >>> y = map(itemgetter(0), x)
    >>> y
    ['Edgar', 'Robert']
    >>> y[0]
    'Edgar'
    >>> y[1]
    'Robert'
    
    0 讨论(0)
  • 2021-01-06 20:58

    I need to send this string to another function.

    If your intention is just to call a function for each string in the list, then there's no need to build a new list, just do...

    def my_function(s):
        # do the thing with 's'
    
    x = [('Edgar',), ('Robert',)]
    
    for (item,) in x:
        my_function(item)
    

    ...or if you're prepared to sacrifice readability for performance, I suspect it's quickest to do...

    def my_function(t):
        s = t[0]        
        # do the thing with 's'
        return None
    
    x = [('Edgar',), ('Robert',)]
    filter(my_function, x)    
    

    Both map() and filter() will do the iteration in C, rather than Python bytecode, but map() will need to build a list of values the same length of the input list, whereas filter() will only build an empty list, as long as my_function() returns a 'falsish' value.

    0 讨论(0)
  • 2021-01-06 20:59

    This is pretty straightforward with a list comprehension:

    x = [('Edgar',), ('Robert',)]
    y = [s for t in x for s in t]
    

    This does the same thing as list(itertools.chain.from_iterable(x)) and is equivalent in behavior to the following code:

    y = []
    for t in x:
        for s in t:
            y.append(s)
    
    0 讨论(0)
提交回复
热议问题