I have:
a = [[1,2],[3,4],[7,10]]
b = [[8,6],[1,9],[2,1],[8,8]]
I want to multiply (pairwise) every element of a with b
1*8+2*6+1*1+2*9+.....+1*8+2*8+3*8+4*6+......+7*8+10*8
Here’s my code so far:
def f(a, b):
new = [x for x in a or x in b]
newer = []
for tuple1, tuple2 in new:
newer.append(map(lambda s,t: s*t, new, new))
return sum(newer)
so my plan of attack was to get all the lists in one list and then multiply everything together. I have seen that lambda work for multiplying lists pairwise but I can’t get it to work for the one list.
Solution:
That kind of combination is called the Cartesian product. I’d use itertools.product for this, which can easily cope with more than 2 lists, if you want.
Firstly, here’s a short demo that shows how to get all of the pairs and how to use tuple assignment to grab the individual elements of the pairs of sublists.
from itertools import product
a = [[1,2],[3,4],[7,10]]
b = [[8,6],[1,9],[2,1],[8,8]]
for (u0, u1), (v0, v1) in product(a, b):
print(u0, u1, v0, v1)
output
1 2 8 6
1 2 1 9
1 2 2 1
1 2 8 8
3 4 8 6
3 4 1 9
3 4 2 1
3 4 8 8
7 10 8 6
7 10 1 9
7 10 2 1
7 10 8 8
And here’s how to find the sum of products that you want.
total = sum(u0 * v0 + u1 * v1 for (u0, u1), (v0, v1) in product(a, b))
print(total)
output
593
Here’s an alternative approach, using the distributive property, as mentioned by Prune.
Firstly, here’s an unreadable list comprehension version. 😉
a = [[1,2],[3,4],[7,10]]
b = [[8,6],[1,9],[2,1],[8,8]]
print(sum([u*v for u,v in zip(*[[sum(t) for t in zip(*u)] for u in (a, b)])]))
output
593
How it works
By the distributive law, the sum you want from the given input data can be written as
(1 + 3 + 7) * (8 + 1 + 2 + 8) + (6 + 9 + 1 + 8) * (2 + 4 + 10)
We can re-arrange the data to produce that expression as follows.
# Use zip to transpose each of the a & b lists.
for u in (a, b):
for t in zip(*u):
print(t)
output
(1, 3, 7)
(2, 4, 10)
(8, 1, 2, 8)
(6, 9, 1, 8)
Now we modify that slightly to get the sums of those lists
# Use zip to transpose each of the a & b lists and compute the partial sums.
partial_sums = []
for u in (a, b):
c = []
for t in zip(*u):
c.append(sum(t))
partial_sums.append(c)
print(partial_sums)
output
[[11, 16], [19, 24]]
Now we just need to multiply the corresponding items of those lists, and add those products together to get the final sum. Once again, we use zip to perform the transposition.
total = 0
for u, v in zip(*partial_sums):
print(u, v)
total += u * v
print(total)
output
11 19
16 24
593