元素明智地添加2个列表?
我现在有:
list1=[1, 2, 3] list2=[4, 5, 6]
我希望有:
[1, 2, 3] + + + [4, 5, 6] || [5, 7, 9]
简单地说就是添加两个列表的元素。
我肯定可以重复这两个列表,但我不想那样做。
什么是最Python的方式这样做?
使用operator.add
map
:
>>> from operator import add >>> 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
其他人给了例子如何在纯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(我发现亨利的版本是最python的版本)。 如果你严重的数字嘎吱嘎吱,让numpy
做沉重的举动。 对于速度怪胎:看起来numpy解决scheme在n = 8
左右开始更快。
[a + b for a, b in zip(list1, list2)]
正如其他人所描述的那样,一个快速且节省空间的解决scheme是使用numpy(np),它具有内置的vector操作function:
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)]
也许“最Python的方式”应该包括处理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)
如果这是你的问题的函数,你可能想要哪个结果?
使用带lambda函数的地图:
>>> map(lambda x, y: x + y, list1, list2) [5, 7, 9]
我没有计时,但我怀疑这会很快:
import numpy as np list1=[1, 2, 3] list2=[4, 5, 6] list_sum = (np.add(list1, list2)).tolist() [5, 7, 9]
这将适用于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]
如果你需要处理不同大小的列表,不要担心! 您所覆盖的精彩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
。
另见这个相关的答案和对另一个问题的评论 。
[list1[i] + list2[i] for i in range(len(list1))]
从我看来,使用numpy
更简单:
import numpy as np list1=[1,2,3] list2=[4,5,6] np.add(list1,list2)
结果:
有关详细的参数信息,请查看: numpy.add
虽然,实际的问题并不想迭代列表来产生结果,但是所有提出的解决scheme都完全不能实现。
刷新:如果不查看所有向量元素,则不能添加两个向量。 所以,这些解决scheme大部分algorithm的复杂性是Big-O(n)。 其中n是vector的维数。
因此,从algorithm的angular度来看,使用for循环迭代生成结果列表也是合乎逻辑和pythonic。 但是,此方法不具有调用或导入任何附加库的开销。
# Assumption: The lists are of equal length. resultList = [list1[i] + list2[i] for i in range(len(list1))]
这里展示/讨论的时间是依赖于系统和实施的,而不能可靠地测量操作的效率。 在任何情况下,vector加法运算的大O复杂度都是线性的,即O(n)。