我现在拥有:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
我希望有:
[1, 2, 3]
+ + +
[4, 5, 6]
|| || ||
[5, 7, 9]
这是两个列表逐元素相加的简单操作。
我可以遍历这两个列表,但我不想这样做。
什么是最符合Python风格的实现方式?
我现在拥有:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
我希望有:
[1, 2, 3]
+ + +
[4, 5, 6]
|| || ||
[5, 7, 9]
这是两个列表逐元素相加的简单操作。
我可以遍历这两个列表,但我不想这样做。
什么是最符合Python风格的实现方式?
map
和operator.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
map
问题在Python3中的注意,这个问题将会变得越来越重要。Python 2将在不到3年的时间内失去官方支持。 - nealmcb其他人给出了如何在纯Python中实现此操作的示例。如果要处理包含10万个元素的数组,建议使用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
左右开始更快。
[a + b for a, b in zip(list1, list2)]
[sum(x) for x in zip(list1, list2)]
与您的答案相同,不是吗? :) - Sibbs Gambling如他人所述,一种快速且占用空间较少的解决方案是使用Numpy(np)及其内置的向量操作能力:
1. 使用Numpy
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)]
在我看来,使用numpy
更简单:
import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)
结果:
有关详细参数信息,请查看此处:numpy.add
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]
也许“最Pythonic的方式”应该包括处理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)
itertools
中的zip_longest
函数,并将fillvalue
设置为0
。 - Ma0numpy.add()
即可。import numpy
list1 = numpy.array([1, 2, 3])
list2 = numpy.array([4, 5, 6])
result = numpy.add(list1, list2) # result receive element-wise addition of list1 and list2
print(result)
array([5, 7, 9])
如果您想接收一个 Python 列表:
result.tolist()
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]
如果你需要处理不同大小的列表,不用担心!神奇的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]
>>>
zip_longest
被称为izip_longest
。