按元素添加2个列表?


Answers:


363

使用mapoperator.add

>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]

zip具有列表理解:

>>> [sum(x) for x in zip(list1, list2)]
[5, 7, 9]

时序比较:

>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in zip(list1, list2)]
1 loops, best of 3: 177 ms per loop

10
如果使用这些巨大的数组,则@BasSwinckels的numpy解决方案可能是您应该关注的问题。
亨利·戈默索尔

1
您在这些计时中使用了哪个Python版本?
arshajii

9
注意:在python3中,map()返回一个可迭代的东西,而不是一个列表。如果您确实需要实际的列表,则第一个答案是list(map(add(list,list1,list2))
FLHerne

map随着时间的推移,注意到@FLHerne指出的python3问题将变得越来越重要。Python 2将在不到3年的时间内失去官方支持。
nealmcb

1
在很多时候,python语法确实非常优雅和简单,但是不幸的是,这并不是其中之一。对于这样一个简单的任务,真是可惜...。当已经有.extend()方法时,为什么要使“ +”连接列表呢?
Nic Sc​​ozzaro

104

其他人给出了如何在纯python中执行此操作的示例。如果要对具有100.000个元素的数组执行此操作,则应使用numpy:

In [1]: import numpy as np
In [2]: vector1 = np.array([1, 2, 3])
In [3]: vector2 = np.array([4, 5, 6])

现在,按元素进行加法与

In [4]: sum_vector = vector1 + vector2
In [5]: print sum_vector
[5 7 9]

就像在Matlab中一样。

与Ashwini最快版本进行比较的时间:

In [16]: from operator import add
In [17]: n = 10**5
In [18]: vector2 = np.tile([4,5,6], n)
In [19]: vector1 = np.tile([1,2,3], n)
In [20]: list1 = [1,2,3]*n
In [21]: list2 = [4,5,6]*n
In [22]: timeit map(add, list1, list2)
10 loops, best of 3: 26.9 ms per loop

In [23]: timeit vector1 + vector2
1000 loops, best of 3: 1.06 ms per loop

因此这快25倍!但是请使用适合您情况的东西。对于一个简单的程序,您可能不想安装numpy,因此请使用标准python(我发现Henry的版本是最Pythonic 的版本)。如果您正认真处理数字,numpy那么就进行繁重的工作。对于速度怪胎:似乎numpy解决方案的运行速度更快n = 8


59
[a + b for a, b in zip(list1, list2)]

4
@deltab可接受的答案更快,并且包含此答案(更有用)
Sibbs Gambling

2
@ perfectionm1ng虽然我理解您的观点(并且一点也不be惜),但我只是想指出,我将始终使用我提供的解决方案(鉴于它不需要导入,因此可以说是最简单的解决方案) (可以说是更出色的Python),或者在速度很重要的情况下,Bas Swinckel的答案是绝对重要的。
亨利·戈默索尔

是。感谢您的意见。但实际上[sum(x) for x in zip(list1, list2)]与您的答案相同,不是吗?:)
Sibbs赌博

4
@ perfectionm1ng或多或少(尽管它是在我的编辑后添加的:)。就个人而言,我更喜欢a + b表示法,并带有明确的元组拆包,以提高可读性和Python感。
亨利·戈默索尔

12

如其他人所述,一种快速且节省空间的解决方案是使用numpy(np)及其内置的矢量处理功能:

1.脾气暴躁

x = np.array([1,2,3])
y = np.array([2,3,4])
print x+y

2.内置

2.1 Lambda

list1=[1, 2, 3]
list2=[4, 5, 6]
print map(lambda x,y:x+y, list1, list2)

注意,map()支持多个参数。

2.2 zip和列表理解

list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in zip(list1, list2)]

1
λ为+1。可耻的是,该解决方案与其他在其他地方重复的解决方案结合在一起。
LondonRob

10

numpy我认为使用起来更简单:

import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)

结果:

终端执行

有关详细的参数信息,请在此处检查:numpy.add


6

也许“最蟒蛇的方式”应该包括处理list1和list2大小不相同的情况。应用其中一些方法会悄悄地为您提供答案。numpy方法会让您知道,很可能是发生ValueError。

例:

import numpy as np
>>> list1 = [ 1, 2 ]
>>> list2 = [ 1, 2, 3]
>>> list3 = [ 1 ]
>>> [a + b for a, b in zip(list1, list2)]
[2, 4]
>>> [a + b for a, b in zip(list1, list3)]
[2]
>>> a = np.array (list1)
>>> b = np.array (list2)
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2) (3)

如果这在您的问题中起作用,您可能想要哪个结果?



5

这将适用于2个或更多列表;遍历列表列表,但使用numpy加法处理每个列表的元素

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

lists = [list1, list2]
list_sum = np.zeros(len(list1))
for i in lists:
   list_sum += i
list_sum = list_sum.tolist()    

[5.0, 7.0, 9.0]

5

也许这是pythonic的,如果列表数量未知且未导入任何内容,则稍微有用。

只要列表的长度相同,就可以使用以下功能。

在这里,* args接受可变数量的列表参数(但每个参数仅求和相同数量的元素)。

在返回的列表中再次使用*来解压缩每个列表中的元素。

def sum_lists(*args):
    return list(map(sum, zip(*args)))

a = [1,2,3]
b = [1,2,3]  

sum_lists(a,b)

输出:

[2, 4, 6]

或有3个清单

sum_lists([5,5,5,5,5], [10,10,10,10,10], [4,4,4,4,4])

输出:

[19, 19, 19, 19, 19]

3

将地图与lambda函数一起使用:

>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]

3

我尚未计时,但我怀疑这会很快:

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

list_sum = (np.add(list1, list2)).tolist()

[5, 7, 9]

3

如果您需要处理不同大小的列表,请不用担心!精彩的itertools模块涵盖了:

>>> from itertools import zip_longest
>>> list1 = [1,2,1]
>>> list2 = [2,1,2,3]
>>> [sum(x) for x in zip_longest(list1, list2, fillvalue=0)]
[3, 3, 3, 3]
>>>

在Python 2中,zip_longest称为izip_longest

另请参阅此相关答案并评论另一个问题


3
[list1[i] + list2[i] for i in range(len(list1))]

1
更多[a + b for (a, b) in zip(list1, list2)]
pythonic

2

虽然,实际的问题并不想遍历列表来生成结果,但是已经提出的所有解决方案实际上都是在后台进行的!

刷新:如果不查看所有矢量元素,则不能添加两个矢量。因此,大多数这些解决方案的算法复杂度为Big-O(n)。其中n是向量的维数。

因此,从算法的角度来看,使用for循环迭代生成结果列表也是逻辑和pythonic的。但是,此外,此方法没有调用或导入任何其他库的开销。

# Assumption: The lists are of equal length.
resultList = [list1[i] + list2[i] for i in range(len(list1))]

这里显示/讨论的时间取决于系统和实现,并且不是测量操作效率的可靠措施。在任何情况下,向量加法运算的大O复杂度都是线性的,即O(n)。


1
a_list = []
b_list = []
for i in range(1,100):
    a_list.append(random.randint(1,100))

for i in range(1,100):
    a_list.append(random.randint(101,200))
[sum(x) for x in zip(a_list , b_list )]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.