具有可变数量元素的附加拆包概括(PEP 448)

问题描述 投票:1回答:2

接受PEP 448Python 3.5引入了额外的拆包概括。

例如:

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]

# unpack both iterables in a list literal
>>> joinedList = [*l1, *l2]
>>> print(joinedList)
[1, 2, 3, 4, 5, 6]

问题:有没有办法用列表列表做类似的事情?

此代码不起作用:

SyntaxError:迭代解包不能用于理解

# List of variable size
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
joined_list = [*l for l in list_of_lists]

当然,您可以执行以下操作,但看起来不那么优雅且看起来效率不高:

# List of variable size
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
joined_list = list()
for l in list_of_lists:
    joined_list += l
python python-3.x iterable-unpacking pep pep448
2个回答
1
投票

去上学怎么样:sum()

Code:

joined_list = sum(list_of_lists, [])

Test Code:

# List of variable size
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
joined_list = sum(list_of_lists, [])
print(joined_list)

Results:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

0
投票

我会劝阻在这里使用sum,因为它是Schlemiel the Painter's algorithm的一种形式。 sum实际上禁止与str;他们没有试图阻止所有的序列使用,以避免减缓sum试图阻止每一次滥用,但它仍然是一个坏主意。

问题在于,这意味着你每次都要逐渐建立更大的临时lists,通过复制你目前所见的所有内容,以及一遍又一遍的新内容,在构建下一个临时版本之后丢弃最后一个临时版本。如果第一个列表中有一百万个项目,并且还有十个lists要连接到它上面,那么你要复制至少1000万个元素(即使其他十个lists是空的)。您的原始代码实际上更好,因为使用+=运算符执行就地扩展,保持O(n)(对于所有ns的list元素)范围的最坏情况性能,而不是O(n*m)(对于n ms的list元素)。

它还有一个只适用于一种类型的问题;如果一些输入是lists,一些tuples和一些生成器,sum将不起作用(因为list.__add__将不接受另一方的非list操作数)。

所以不要这样做。这是what itertools.chain and it's alternate constructor, itertools.chain.from_iterable were made for

from itertools import chain

list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
joined_list = list(chain.from_iterable(list_of_lists))

它保证O(n),适用于您抛出的任何迭代,等等。

是的,很明显,如果你只有三个元素的三个lists,它几乎不重要。但是如果输入迭代的大小或迭代的数量是任意大的,或者类型不一致,chain将起作用,sum将不会。

© www.soinside.com 2019 - 2024. All rights reserved.