Python元组列表,需要解压缩和清理

时间:2021-05-23 20:26:52

Assume you have a list such as

假设您有一个列表,如

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

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

What would be the most efficient way to get to just the strings 'Edgar' and 'Robert'?

什么是最有效的方式来达到字符串'埃德加'和'罗伯特'?

Don't really want x[0][0], for example.

例如,不要真的需要x [0] [0]。

5 个解决方案

#1


6  

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)

#2


3  

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:

这与list(itertools.chain.from_iterable(x))的作用相同,并且在行为上等效于以下代码:

y = []
for t in x:
    for s in t:
        y.append(s)

#3


2  

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.

map()和filter()都将在C中进行迭代,而不是Python字节码,但map()需要构建一个与输入列表长度相同的值列表,而filter()只会构建一个空列表,只要my_function()返回'falsish'值。

#4


2  

Here is one way:

这是一种方式:

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

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

注意逗号的位置,它解压缩元组。

#5


1  

>>> from operator import itemgetter
>>> y = map(itemgetter(0), x)
>>> y
['Edgar', 'Robert']
>>> y[0]
'Edgar'
>>> y[1]
'Robert'

#1


6  

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)

#2


3  

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:

这与list(itertools.chain.from_iterable(x))的作用相同,并且在行为上等效于以下代码:

y = []
for t in x:
    for s in t:
        y.append(s)

#3


2  

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.

map()和filter()都将在C中进行迭代,而不是Python字节码,但map()需要构建一个与输入列表长度相同的值列表,而filter()只会构建一个空列表,只要my_function()返回'falsish'值。

#4


2  

Here is one way:

这是一种方式:

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

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

注意逗号的位置,它解压缩元组。

#5


1  

>>> from operator import itemgetter
>>> y = map(itemgetter(0), x)
>>> y
['Edgar', 'Robert']
>>> y[0]
'Edgar'
>>> y[1]
'Robert'