How can I sum the product of two list items using for loop in python?

Question:

I am trying to sum the product of two different list items in the same line using for loop, but I am not getting the output as expected.

My example code:

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

sum = 0              # optional element

score = ((sum+(a(i)*b(i)) for i in range(len(a)))

print score

output:

<generator object <genexpr> at 0x027284B8>

expected output:

32                   # 0+(1*4)+(2*5)+(3*6)
Asked By: Ravy

||

Answers:

Just zip the lists to generate pairs, multiply them and feed to sum:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> sum(x * y for x, y in zip(a, b))
32

In above zip will return iterable of tuples containing one number from both lists:

>>> list(zip(a, b))
[(1, 4), (2, 5), (3, 6)]

Then generator expression is used to multiply the numbers together:

>>> list(x*y for x, y in list(zip(a, b)))
[4, 10, 18]

Finally sum is used to sum them together for final result:

>>> sum(x*y for x, y in list(zip(a, b)))
32
Answered By: niemmi

You have some problems in your code, first off you cant index your list with parenthesis you need [], secondly you’ve created a generator not a number.

You need to zip your lists first:

In [3]: sum(i*j for i,j in zip(a, b))
Out[3]: 32

Or as a functional approach use operator.mul within map and sum:

In [11]: from operator import mul 

In [12]: sum(map(mul, a, b))
Out[12]: 32
Answered By: Mazdak

You can try:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> sum(map(lambda x: x[0] * x[1], zip(a, b)))
32
Answered By: Harsha Biyani
a = [1,2,3]
b = [4,5,6]
ls = [x * y for x, y in zip(a, b)]
x = sum(ls) 
print x
Answered By: Shivkumar kondi

Let’s take a close look at your code:

score = ((sum+(a(i)*b(i)) for i in range(len(a)))

The right hand side of this statement is a generator expression. Think of a generator as a lazy list. It doesn’t actually sum anything, so to be more correct you should do

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

(Note the brackets, not parentheses, for subscripting the lists.)

Now score is a generator which “contains” the products of corresponding elements of the original lists a and b.

The next step is to iterate over the list to sum the elements:

for x in score:
    sum += x
print(sum)

As others have already posted, you can do this all in one line with zip() and sum() built-in functions:

sum([x*y for x, y in zip(a, b)])
Answered By: Code-Apprentice

A generator by itself, even if applied so as to generate the list result, will just give you a list of the products. You still need to do something to add up the elements of the list, which you can’t do inside your generator.

Your method looks like you’ve mixed generator syntax with a traditional for loop, which would look like this:

score = 0
for i in range(len(a)):
  score = score + a[i]*b[i]

The cleanest, or at least most Pythonic, solution probably uses zip to combine the lists, a list comprehension to multiply the elements, and sum to add them all up:

score = sum([x*y for (x,y) in zip(a,b)])

You could also use reduce for the full-on functional approach (note that you have to import it from functools if you use Python 3):

score = reduce(lambda s,t: s+t[0]*t[1], zip(a,b), 0)
Answered By: Mark Reed

If you have a large list, you might consider taking the dot product using numpy arrays

import numpy as np
arr1 = np.random.randint(0,2,300)
arr2 = np.random.randint(0,2500,300)

list1 = list(arr1)
list2 = list(arr2)

%timeit sum([x * y for x, y in zip(list1,list2)])

38.9 µs ± 795 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit arr1 @ arr2

1.23 µs ± 89.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Answered By: thetinymite

an unconventional method: the LAMBDA function.

a = [1,2,3]
b = [4,5,6]
pwr = sum(map(lambda a,b:a*b, a,b))
print(pwr)
Answered By: Emir

Since Python 3.12, there is a new built-in function in the math module – sumprod:

from math import sumprod

a = [1,2,3]
b = [4,5,6]
print(sumprod(a, b))
# 32
Answered By: Tomerikoo
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.