我正在使用python 3.6。我通过以下方式使用sum
来展平嵌套列表:
a = [[1, 2], [3, 4], [5, 6]]
sum(a,[])
返回:
[1,2,3,4,5,6]
这到底发生了什么? Sum采用可迭代的,在这种情况下是一个列表,以及一个起始值。我不明白python读取什么来压扁列表。
答案 0 :(得分:9)
这只是Python解释添加列表的结果。来自docs
sum(iterable[, start])
从左到右汇总开始和迭代的项目并返回总数。
由于sum
首先将iterable的第一个元素添加到start
参数,所以你有:
[] + [1, 2] = [1, 2]
然后继续添加来自iterable的项目:
[1, 2] + [3, 4] = [1, 2, 3, 4]
[1, 2, 3, 4] + [5, 6] = [1, 2, 3, 4, 5, 6]
答案 1 :(得分:7)
sum([a, b, c], d)
生成d + a + b + c
。
在您的示例中,a
,b
,c
和d
为[1, 2]
,[3, 4]
,[5, 6]
,和[]
。
sum([[1, 2], [3, 4], [5, 6]], [])
生成[] + [1, 2] + [3, 4] + [5, 6]
,[1, 2, 3, 4, 5, 6]
,因为+
是列表的连接。
这是荒谬的低效,因为涉及的每个+
操作都需要从每个参数中复制所有数据:
In [7]: x = [[i] for i in range(30000)]
In [8]: %timeit sum(x, [])
1 loop, best of 3: 2.06 s per loop
In [9]: %timeit [elem for sublist in x for elem in sublist]
1000 loops, best of 3: 1.91 ms per loop
sum(x, [])
需要二次时间,而更有效的实现需要线性时间。永远不要sum(x, [])
。
答案 2 :(得分:6)
正如sum(iterable[, start])
文件所说:
从左到右汇总
start
和iterable
项,并返回总数。start
默认为0.iterable
的项通常是数字,起始值不允许是字符串。
所以,在你分享的例子中:
sum(a,[])
此处iterable
为a
([[1, 2], [3, 4], [5, 6]]
),start
为[]
。因此,结果相当于:
[] + [1, 2] + [3, 4] + [5, 6]
# i.e. you flatten list --> [1, 2, 3, 4, 5, 6]
答案 3 :(得分:2)
start
参数赋予函数起点。这是正在添加的内容。因此sum([1,2,3])
会返回6
而sum([1,2,3],5)
会返回11
。在您的情况下,因为您传入了2-d列表和空列表,该函数将把第一个参数中的所有内容添加到第二个参数中。基本上,你是这样做的:
[]+[1,2]+[3,4]+[5,6]
这是python运算符重载的一个怪癖。