172

I want to perform an element wise multiplication, to multiply two lists together by value in Python, like we can do it in Matlab.

This is how I would do it in Matlab.

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

A list comprehension would give 16 list entries, for every combination x * y of x from a and y from b. Unsure of how to map this.

If anyone is interested why, I have a dataset, and want to multiply it by Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

martineau
  • 112,593
  • 23
  • 157
  • 280
xxjjnn
  • 13,690
  • 19
  • 56
  • 86

15 Answers15

330

Use a list comprehension mixed with zip():.

[a*b for a,b in zip(lista,listb)]
gahooa
  • 122,825
  • 12
  • 91
  • 98
  • 10
    On the other hand, if they want to do anything else beyond the trivial case here the OP would be well advised to use Numpy. – Henry Gomersall Apr 22 '12 at 20:41
  • 1
    On Python 2 izip() could be a better choice. – yak Apr 22 '12 at 21:16
  • 31
    You can also use `map(lambda x,y:x*y,lista,listb)`. – mbomb007 Jun 16 '15 at 21:20
  • How would the answer change if we are given instead of `listb` a rather list of elements of type `listb` are given and we need to operate to obtain a single list. Ex. (x, pi, e) with [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], when taken (x, pi, e) operated with (4, 5, 2) and then (x, pi, e) operated with (1, 2, 4) ... so on. – gxyd Jul 09 '17 at 17:03
  • @gxyd You should ask a separate question – mbomb007 Aug 09 '18 at 13:32
  • Just to add to what 'mbomb007' stated. To get this into a list form, you would need to use `list(map(lambda x ,y: x * y, lista, listb))` – FlamePrinz Jul 18 '19 at 19:18
  • For me, it takes longer to understand zipping and then doing something with 2 values of every tuple than for instance the solution with `map` and `operator.mul`. – xuiqzy May 03 '20 at 17:17
99

Since you're already using numpy, it makes sense to store your data in a numpy array rather than a list. Once you do this, you get things like element-wise products for free:

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])
NPE
  • 464,258
  • 100
  • 912
  • 987
  • 1
    Maybe not the most scientific, but I timed this against gahooa's answer using timeit. Numpy is actually slightly slower than the zip method. – Chase Roberts Aug 15 '15 at 14:09
  • 1
    In my case, where the lists contained binary values, the numpy solution was much faster than using the izip. – Serendipity Sep 01 '15 at 07:55
  • For the benefit of others arriving here from a google search I have included a timeit comparison below. – paddyg Nov 08 '16 at 11:10
39

Use np.multiply(a,b):

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)
Brisa
  • 448
  • 4
  • 7
23

You can try multiplying each element in a loop. The short hand for doing that is

ab = [a[i]*b[i] for i in range(len(a))]
Prabhu
  • 5,045
  • 4
  • 35
  • 44
Nate
  • 239
  • 2
  • 2
  • welcome to stackoverflow! code-only answers are generally discouraged - please add some explanation as to how this solves the questioner's question. – Corley Brigman Mar 07 '14 at 05:41
  • 9
    @CorleyBrigman I disagree; there is very little difference between an answer which is "Here is a way of doing this: " and just "". In this particular situation, there is little to explain other than "this code solves your problem". – icedtrees Mar 07 '14 at 05:44
  • 5
    @CorleyBrigman I disagree; an example data with displaying the results would actually be more helpful – Tjorriemorrie May 14 '14 at 07:29
  • 2
    This is how a C, C++, or Java programmer who is a Python novice would solve the problem. The [accepted answer](http://stackoverflow.com/a/10271504/3657941) is idiomatic Python. – David Cullen Mar 08 '17 at 15:16
  • @Tjorriemorrie the results are clear as they are explicitly requested in the question. maybe an explanation of how list comprehensions work could be nice or mentioning that this makes use of list comprehension and then everybody can look that up, if they don't know it. – xuiqzy May 03 '20 at 17:04
13

Yet another answer:

-1 ... requires import
+1 ... is very readable

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

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

outputs [10, 22, 36, 52]

Petr Vepřek
  • 1,389
  • 2
  • 22
  • 32
  • 1
    If you know map, this is a really readable solution! Does the import have any negative consequence apart from being there at the top of the file? (editors can hide imports if they want) As far as I can see, it should be available in every python 2 and 3 version! – xuiqzy May 03 '20 at 17:15
  • Very nice functional solution! – janniks May 27 '21 at 19:00
10

Fairly intuitive way of doing this:

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
Turtleneck
  • 101
  • 1
  • 2
10

you can multiplication using lambda

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

For large lists, we can do it the iter-way:

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

product_iter_object.next() gives each of the element in the output list.

The output would be the length of the shorter of the two input lists.

0xdeadbeef
  • 404
  • 2
  • 12
aady
  • 35
  • 2
4

create an array of ones; multiply each list times the array; convert array to a list

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]
litepresence
  • 2,835
  • 1
  • 26
  • 33
4

The map function can be very useful here. Using map we can apply any function to each element of an iterable.

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

Of course:

map(f, iterable)

is equivalent to

[f(x) for x in iterable]

So we can get our solution via:

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

In Python 2.x map() means: apply a function to each element of an iterable and construct a new list. In Python 3.x, map construct iterators instead of lists.

Instead of my_mul we could use mul operator

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

Please note that since map() constructs an iterator we use * iterable unpacking operator to get a list. The unpacking approach is a bit faster then the list constructor:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>
sg7
  • 5,668
  • 2
  • 31
  • 39
3

Can use enumerate.

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

ab = [val * b[i] for i, val in enumerate(a)]
SuperNova
  • 21,204
  • 6
  • 80
  • 55
3

gahooa's answer is correct for the question as phrased in the heading, but if the lists are already numpy format or larger than ten it will be MUCH faster (3 orders of magnitude) as well as more readable, to do simple numpy multiplication as suggested by NPE. I get these timings:

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

i.e. from the following test program.

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))
paddyg
  • 2,063
  • 18
  • 23
2

To maintain the list type, and do it in one line (after importing numpy as np, of course):

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

or

list(np.array(a) * np.array(b))
mightypile
  • 7,000
  • 3
  • 32
  • 36
0

you can use this for lists of the same length

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
WOX GAMER
  • 1
  • 2
0
import ast,sys
input_str = sys.stdin.read()

input_list = ast.literal_eval(input_str)

list_1 = input_list[0]

list_2 = input_list[1]

import numpy as np

array_1 = np.array(list_1)

array_2 = np.array(list_2)

array_3 = array_1*array_2


print(list(array_3))
Suraj Rao
  • 28,850
  • 10
  • 94
  • 99
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. [From Review](/review/low-quality-posts/27925056) – double-beep Dec 24 '20 at 16:08