接受 PEP 448
已在Python 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
答案 0 :(得分:1)
去读旧学怎么样:sum()
joined_list = sum(list_of_lists, [])
# 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)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
答案 1 :(得分:0)
我不鼓励在这里使用sum
,因为它是Schlemiel the Painter's algorithm的一种形式。 sum
实际上禁止使用str
;他们并没有尝试阻止所有序列使用,以免降低sum
的尝试速度,以阻止每次滥用,但这仍然不是一个好主意。
问题在于,这意味着您每次都会构建逐渐变大的临时list
,在复制下一个 之后,您将在构建下一个临时list
时将其丢弃,再加上新的东西。如果第一个列表中有一百万个项目,并且您还有十个以上的list
串联在一起,那么您正在复制至少一千万个元素(即使其他十个+=
是空的) )。您的原始代码实际上更好,因为使用O(n)
运算符执行了就地扩展,在n
中保持了最差情况的性能(对于所有list
的{{1}}元素s)范围,而不是O(n*m)
(对于n
m
s中的list
个元素)。
它还具有仅适用于一种一致类型的问题;如果某些输入是list
,某些tuple
和某些生成器,则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)
,它可以与您扔给它的所有可迭代项一起使用,等等。
是的,很显然,如果您只得到三个元素中的三个list
,就没关系了。但是,如果输入可迭代项的大小或可迭代项的数量任意大,或者类型不一致,则chain
将起作用,sum
将不会起作用。