Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to multiply/add/devide each element of a list with each element of another list in Python

I want to multiply each element of a list with each element of another list.

lst1 = [1, 2, 1, 2]
lst2 = [2, 2, 2]

lst3 = []

for item in lst1:
    for i in lst2:
        rs = i * item
        lst3.append(rs)

This would work, but this is very inefficient in large dataset and can take very long to complete loop. Note, the length of both lists can vary here.

I am fine with using non built-in data structures. I checked numpy and there seems to be way called broadcasting in ndarray. I am not sure if it is way to go. So far, multiplying array with scalar works as expected.

arr = np.arange(3)
arr * 2

This returns:

array([0, 2, 4])

But they way it works with another array is bit different and I can't seem to achieve above.

I guess it must be something straight forward, but I can't seem to find exact solution needed at the moment. Any input will be highly appreciated. Thanks.

Btw, there is similar question for Scheme without considering efficiency here

Edit: Thanks for you answers. Multiplication works, see Dval's answer. However, I also need to do addition and possibly division too exactly same way. For that reason, I updated question a bit.

Edit: I can work with numpy array itself, so I don't need to convert list to array and back.

like image 254
chhantyal Avatar asked Dec 02 '25 15:12

chhantyal


2 Answers

Numpy is the way to go, specifically numpy.outer, which returns the product of each element as a matrix. Using .flatten() compresses it into 1d.

import numpy
lst1 = numpy.array([1, 2, 1, 2])
lst2 = numpy.array([2, 2, 2])
numpy.outer(lst1, lst2).flatten()

To add to updated question, addition seems to work similar way:

numpy.add.outer(lst1, lst2).flatten()
like image 191
Dval Avatar answered Dec 04 '25 03:12

Dval


Linear operations on arrays like this are the meat-n-potatoes of numpy. Once you have defined the arrays, matrix like operations on them are easy, and relatively fast. That includes outer products and inner (matrix) products, as well as element by element operations.

For example:

In [133]: a=np.array([1,2,1,2])
In [134]: b=np.array([2,2,2])

A list comprehension version of your double loop:

In [135]: [i*j for i in a for j in b]
Out[135]: [2, 2, 2, 4, 4, 4, 2, 2, 2, 4, 4, 4]

A numpy product using broadcasting. Think a a[:,None] as turning a into a column vector.

In [136]: a[:,None]*b
Out[136]: 
array([[2, 2, 2],
       [4, 4, 4],
       [2, 2, 2],
       [4, 4, 4]])

element by element division also works

In [137]: a[:,None]/b
Out[137]: 
array([[ 0.5,  0.5,  0.5],
       [ 1. ,  1. ,  1. ],
       [ 0.5,  0.5,  0.5],
       [ 1. ,  1. ,  1. ]])

But this gets more useful when combining operations.

There is overhead in converting lists to arrays, so I wouldn't recommend it for small occasional calculations.

like image 44
hpaulj Avatar answered Dec 04 '25 05:12

hpaulj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!