如何执行两个列表的按元素相乘?


137

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

这就是我在Matlab中要做的。

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

对于from 和from的每个组合x * y,列表理解将给出16个列表条目。不确定如何映射。xayb

如果有人对此感兴趣,我有一个数据集,并想乘以Numpy.linspace(1.0, 0.5, num=len(dataset)) =)


4
为什么现在已经有关于numpy的问题?
pwuertz

2
顺便说一下,这是逐元素乘法,这不是点积。
pwuertz

3
备选:map(lambda x,y:x * y,list1,list2)#derp ...
xxjjnn 2012年

Answers:


284

使用列表理解与zip():混合。

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

9
另一方面,如果他们想做一些琐碎的事情,OP最好使用Numpy。
亨利·戈默索尔

1
在Python 2上,izip()可能是更好的选择。
yak 2012年

23
您也可以使用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 '18

87

由于您已经在使用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快得多。
巧遇2015年

为了其他人从谷歌搜索到达这里的利益,我在下面提供了一个时间比较。
paddyg '16

31

使用np.multiply(a,b):

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

21

您可以尝试将每个元素乘以一个循环。这样做的捷径是

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

欢迎来到stackoverflow!通常不建议仅使用代码的答案-请添加一些有关如何解决提问者问题的解释。
Corley Brigman 2014年

7
@CorleyBrigman我不同意;答案“这是一种实现方法:<code>”和仅“ <code>”之间几乎没有区别。在这种特殊情况下,除了“此代码解决了您的问题”之外,几乎没有其他解释。
icedtrees 2014年

4
@CorleyBrigman我不同意;显示结果的示例数据实际上会更有帮助
Tjorriemorrie 2014年

2
这是Python新手的C,C ++或Java程序员如何解决该问题。该接受的答案是地道的Python。
David Cullen

@Tjorriemorrie的结果很明确,因为问题中已明确要求它们。也许对列表理解如何工作的解释可能很好,或者提到这利用了列表理解,然后每个人都可以查找(如果他们不知道的话)。
xuiqzy

10

还有一个答案:

-1...需要导入
+1...非常易读

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

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

输出[10、22、36、52]


如果您知道地图,这是一个非常易读的解决方案!除了位于文件顶部之外,导入是否还会有负面影响?(编辑可以根据需要隐藏导入)据我所知,每个python 2和3版本都应该可用!
xuiqzy

9

相当直观的方法:

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

9

您可以使用 lambda

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

4

对于大型列表,我们可以反复进行:

product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])

product_iter_object.next() 给出输出列表中的每个元素。

输出将是两个输入列表中较短者的长度。


4

创建一个数组;将每个列表乘以数组;将数组转换为列表

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]

3

gahooa的答案对于标题中所述的问题是正确的,但是如果列表已经是numpy格式大于十,它将更快(3个数量级)并且可读性更高,如NPE。我得到这些时间:

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

3

可以使用枚举。

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

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

3

map功能在这里可能非常有用。使用map我们可以将任何函数应用于可迭代对象的每个元素。

Python 3.x

>>> def my_mul(x,y):
...     return x*y
...
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>>
>>> list(map(my_mul,a,b))
[2, 6, 12, 20]
>>>

当然:

map(f, iterable)

相当于

[f(x) for x in iterable]

因此,我们可以通过以下方式获得解决方案:

>>> [my_mul(x,y) for x, y in zip(a,b)]
[2, 6, 12, 20]
>>>

在Python 2.x中map()意味着:将函数应用于可迭代的每个元素并构造一个新列表。在Python 3.x中,map构造迭代器而不是列表。

代替my_mul我们可以使用 mul运算符

Python 2.7

>>>from operator import mul # import mul operator
>>>a = [1,2,3,4]
>>>b = [2,3,4,5]
>>>map(mul,a,b)
[2, 6, 12, 20]
>>>

Python 3.5+

>>> from operator import mul
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>> [*map(mul,a,b)]
[2, 6, 12, 20]
>>>

请注意,由于map()构造了迭代器,因此我们使用*可迭代的拆包运算符来获取列表。解压缩方法比list构造函数要快一些:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>

1

要维护列表类型,并在一行中完成(当然,在将numpy导入为np之后):

list(np.array([1,2,3,4]) * np.array([2,3,4,5]))

要么

list(np.array(a) * np.array(b))

0

您可以将其用于相同长度的列表

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
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.