1

接受在. 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
4

2 回答 2

2

去老学校怎么样: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]
于 2018-02-12T03:02:35.450 回答
0

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

问题在于,这意味着您每次都构建逐渐变大的临时s,在构建下一个临时文件后,通过一遍又一遍地复制您迄今为止看到的所有内容list以及新的东西来丢弃最后一个临时文件。如果第一个列表中有 100 万个项目,并且您还有 10 个s 可以连接到它上面,那么您将复制至少 1000 万个元素(即使其他 10 个s 是空的)。您的原始代码实际上更好,因为使用运算符执行就地扩展,将最坏情况的性能保持在(对于所有s 的元素)范围内,而不是(对于跨s 的元素)。listlist+=O(n)nlistO(n*m)nm list

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

所以不要那样做。这就是itertools.chain的替代构造函数,itertools.chain.from_iterable用于

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不会。

于 2019-03-22T20:27:00.353 回答