使用`sum(iterable,[])`如何使嵌套列表变平?

时间:2018-04-17 21:09:12

标签: python python-3.x list

我正在使用python 3.6。我通过以下方式使用sum来展平嵌套列表:

a = [[1, 2], [3, 4], [5, 6]]

sum(a,[])

返回:

[1,2,3,4,5,6]

这到底发生了什么? Sum采用可迭代的,在这种情况下是一个列表,以及一个起始值。我不明白python读取什么来压扁列表。

4 个答案:

答案 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

在您的示例中,abcd[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])文件所说:

  

从左到右汇总startiterable项,并返回总数start默认为0. iterable的项通常是数字,起始值不允许是字符串。

所以,在你分享的例子中:

sum(a,[])

此处iterablea [[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])会返回6sum([1,2,3],5)会返回11。在您的情况下,因为您传入了2-d列表和空列表,该函数将把第一个参数中的所有内容添加到第二个参数中。基本上,你是这样做的:

[]+[1,2]+[3,4]+[5,6]

这是python运算符重载的一个怪癖。