312

我现在有了:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

我希望拥有:

[1, 2, 3]
 +  +  +
[4, 5, 6]
|| || ||
[5, 7, 9]

只需按元素添加两个列表。

我当然可以迭代这两个列表,但我不想这样做。

这样做的最 Pythonic 方式是什么?

4

16 回答 16

436

Use map with operator.add:

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

or zip with a list comprehension:

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

Timing comparisons:

>>> 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
于 2013-09-10T07:50:36.300 回答
123

其他人给出了如何在纯 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.

于 2013-09-10T07:59:11.603 回答
69
[a + b for a, b in zip(list1, list2)]
于 2013-09-10T07:51:57.377 回答
14

正如其他人所描述的,一个快速且节省空间的解决方案是使用 numpy (np) 及其内置的向量操作功能:

1. 使用 Numpy

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

2.内置插件

2.1 拉姆达

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

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

2.2 压缩和列表理解

list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in zip(list1, list2)]
于 2016-10-07T22:31:22.243 回答
12

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

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

结果:

终端执行

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

于 2017-08-06T20:57:49.680 回答
8

如果您有未知数量的列表并且没有导入任何内容,那么这可能是 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]
于 2019-05-19T13:55:00.850 回答
7

也许“最 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)

如果这是您问题中的一个函数,您可能想要哪个结果?

于 2014-02-11T22:10:12.337 回答
6

这很简单numpy.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()
于 2018-01-03T01:47:19.723 回答
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]
于 2015-12-23T15:27:45.867 回答
4

If you need to handle lists of different sizes, worry not! The wonderful itertools module has you covered:

>>> 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]
>>>

In Python 2, zip_longest is called izip_longest.

See also this relevant answer and comment on another question.

于 2016-09-19T16:16:57.410 回答
4
[list1[i] + list2[i] for i in range(len(list1))]
于 2016-03-06T14:33:57.047 回答
3

使用带有 lambda 函数的 map:

>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]
于 2014-08-24T08:27:34.307 回答
3

我还没有计时,但我怀疑这会很快:

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

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

[5, 7, 9]
于 2015-12-23T14:49:24.540 回答
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)。

于 2017-04-01T14:07:19.373 回答
2
  • zip 函数在这里很有用,与列表推导一起使用v1v2.
  • 如果您有一个列表列表(而不仅仅是两个列表),您可以使用v3.
  • 对于具有不同长度的列表(例如:通过在第一个/第二个列表的末尾添加 1),那么您可以尝试这样的事情(使用 zip_longest) -v4
first = [1, 2, 3, 1]
second = [4, 5, 6]

output: [5, 7, 9, 1]
  • 如果您有未知数量的相同长度的列表,您可以使用函数v5.

  • v6- operator 模块导出一组与 Python 内在运算符相对应的高效函数。例如,operator.add(x, y)等价于表达式x+y

  • v7- 假设两个列表具有相同的长度firstsecond您不需要 zip 或其他任何东西。

################
first = [1, 2, 3]
second = [4, 5, 6]

####### v1 ########
third1 = [sum(i) for i in zip(first,second)]

####### v2 ########
third2 = [x + y for x, y in zip(first, second)]

####### v3 ########
lists_of_lists = [[1, 2, 3], [4, 5, 6]]
third3 = [sum(x) for x in zip(*lists_of_lists)]

####### v4 ########
from itertools import zip_longest
third4 = list(map(sum, zip_longest(first, second, fillvalue=0)))

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

third5 = sum_lists(first, second)

####### v6 ########
import operator
third6 = list(map(operator.add, first,second))

####### v7 ########
third7 =[first[i]+second[i] for i in range(len(first))]

####### v(i) ########

print(third1) # [5, 7, 9]
print(third2) # [5, 7, 9]
print(third3) # [5, 7, 9]
print(third4) # [5, 7, 9]
print(third5) # [5, 7, 9]
print(third6) # [5, 7, 9]
print(third7) # [5, 7, 9]
于 2020-08-05T07:15:46.727 回答
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 )]
于 2019-06-03T22:51:51.793 回答