如何对两个列表进行逐元素乘法运算?

191

我想要在Python中执行逐元素乘法,将两个列表按值相乘,就像我们可以在Matlab中做的那样。

这是我在Matlab中的操作方式。

a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]

使用列表推导式会产生16个列表项,对于从a中选出的每个x和从b中选出的每个y的组合x * y。不确定如何进行映射。

如果有人感兴趣为什么,我有一个数据集,并希望将其乘以Numpy.linspace(1.0, 0.5, num=len(dataset)) =)


5
你已经了解numpy,为什么还要问这个问题? - pwuertz
4
顺便提一下,这是逐元素相乘,而不是点积。 - pwuertz
3
替代方案:map(lambda x, y: x*y, list1, list2) # 呃... - xxjjnn
这个问题已经有了答案,_列出了一个在我之后两年发布的问题_。我真傻,应该去未来看看。 - xxjjnn
15个回答

360

使用混合 zip() 的列表推导式:

[a*b for a,b in zip(lista,listb)]

10
另一方面,如果他们想做超出这里所示琐碎情况的任何其他事情,建议使用Numpy。 - Henry Gomersall
1
在Python 2中,izip()可能是更好的选择。 - yak
34
您还可以使用 map(lambda x,y:x*y,lista,listb)。该函数会将两个列表中对应的元素相乘,返回一个由结果组成的新列表。 - mbomb007
如果我们不是给出listb而是给出类型为listb的元素列表,并且我们需要进行操作以获得单个列表,那么答案会如何改变。例如:(x, pi, e)与[(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)],当使用(x, pi, e)与(4, 5, 2)进行操作,然后使用(x, pi, e)与(1, 2, 4)进行操作...以此类推。 - gxyd
@gxyd 你应该提出一个单独的问题。 - mbomb007
显示剩余3条评论

107

既然您已经在使用 numpy,将数据存储在 numpy 数组中而不是列表中是很有意义的。一旦这样做,您就可以免费获得诸如逐元素乘积之类的内容:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: b = np.array([2,3,4,5])

In [4]: a * b
Out[4]: array([ 2,  6, 12, 20])

1
也许不是最科学的方法,但我使用timeit对比了gahooa的答案。NumPy比zip方法稍微慢一些。 - Chase Roberts
1
在我的情况下,由于列表包含二进制值,使用numpy的解决方案比使用izip要快得多。 - Serendipity
1
为了方便从谷歌搜索到这里的其他人,我在下面包含了一个timeit比较。 - paddyg

42

使用np.multiply(a,b)函数:

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)

1
结果是一个np.array [2 6 12 20],而不是一个Python列表[2, 6, 12, 20]。但是如果你需要一个Python列表,你可以写成 np.multiply(a,b).tolist()。 - Convexity

23

你可以在循环中尝试将每个元素相乘。该操作的简写方式是:

ab = [a[i]*b[i] for i in range(len(a))]

欢迎来到StackOverflow!仅有代码的答案通常不被鼓励 - 请添加一些解释说明如何解决提问者的问题。 - Corley Brigman
10
@CorleyBrigman 我不同意;“这是一种做法:<code>”和仅仅是“<code>”之间几乎没有什么区别。在这种特定情况下,除了“这段代码解决了你的问题”之外,几乎没有什么需要解释的了。 - icedtrees
5
@CorleyBrigman 我不同意;提供一个带有结果展示的数据示例会更有帮助。 - Tjorriemorrie
2
这是一个C、C++或Java程序员如何解决问题的Python新手。被接受的答案是惯用的Python。 - user3657941
@Tjorriemorrie,结果很清楚,因为它们在问题中明确请求。也许解释一下列表推导式的工作原理会很好,或者提到这是使用列表推导式,然后每个人都可以查找它,如果他们不知道它。 - xuiqzy

15

另一个答案:

-1 ... 需要导入
+1 ... 很易读

import operator
a = [1,2,3,4]
b = [10,11,12,13]

list(map(operator.mul, a, b))

输出 [10, 22, 36, 52]

编辑

对于Python3.6+,map不会自动解包值。

请使用itertools.starmap

import itertools
import operator

itertools.starmap(operator.mul, zip(a, b)))

1
如果你了解map函数,这是一个非常易读的解决方案!除了在文件顶部存在之外,导入是否有任何负面影响?(如果编辑器希望,它们可以隐藏导入)就我所知,它应该在每个Python 2和3版本中都可用! - xuiqzy
非常好的功能性解决方案! - janniks

12

你可以使用 lambda 进行乘法运算

foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)

在Python 3中,将list(map(lambda x,y:x*y,foo,bar))翻译成中文。 - undefined

10
相当直观的做法:
a = [1,2,3,4]
b = [2,3,4,5]
ab = []                        #Create empty list
for i in range(0, len(a)):
     ab.append(a[i]*b[i])      #Adds each element to the list

5

如果列表已经是numpy格式或者长度大于10,那么建议使用NPE所建议的简单的numpy乘法来进行计算。这样做速度会更快(3个数量级),并且更易读。对于标题中提出的问题,gahooa的答案是正确的。我得到以下时间:

0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 4, a = np.arange(N), c = a * b
0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 40, a = np.arange(N), c = a * b
0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0020ms -> N = 400, a = np.arange(N), c = a * b

即从以下测试程序中。
import timeit

init = ['''
import numpy as np
N = {}
a = {}
b = np.linspace(0.0, 0.5, len(a))
'''.format(i, j) for i in [4, 40, 400] 
                  for j in ['[i for i in range(N)]', 'np.arange(N)']]

func = ['''c = [a*b for a,b in zip(a, b)]''',
'''c = a * b''']

for i in init:
  for f in func:
    lines = i.split('\n')
    print('{:6.4f}ms -> {}, {}, {}'.format(
           timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))

4

创建一个元素全为1的数组; 将每个列表分别与该数组相乘; 将数组转换为列表。

import numpy as np

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

c = (np.ones(len(a))*a*b).tolist()

[2.0, 6.0, 12.0, 20.0]

4
可以使用enumerate函数。
a = [1, 2, 3, 4]
b = [2, 3, 4, 5]

ab = [val * b[i] for i, val in enumerate(a)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接