HogRider123 HogRider123 - 1 month ago 8
Python Question

Element-wise product of two 2-D lists

(I can't use Numpy or any other library function as this is a question I have to do, I have to define my own way. Thankyou.)

I am writing a function that takes two lists (2 dimensional) as arguments. The function should calculate the element-wise product of both lists and store them in a third list and return this resultant list from the function.
An example of the input lists are:

list1:



[[2,3,5,6,7],[5,2,9,3,7]]


list2:



[[5,2,9,3,7],[1,3,5,2,2]]


The function prints the following list:

[[10, 6, 45, 18, 49], [5, 6, 45, 6, 14]]


That is 2*5=10, 3*2=6, 5*9=45 ... and so on.

This is my code below, but it is only for a list with 2 lists (elements) inside in it like the example above and works perfectly fine for that, but what I want is to edit my code so that no matter how many number of lists (elements) are there in the 2-D list, it should print out its element-wise product in a new 2-D list. Eg, it should also work for

[[5,2,9,3,7],[1,3,5,2,2],[1,3,5,2,2]]


or

[[5,2,9,3,7],[1,3,5,2,2],[1,3,5,2,2],[5,2,9,3,7]]


or any number of lists there are within the whole list.

def ElementwiseProduct(l,l2):
i=0
newlist=[] #create empty list to put prouct of elements in later
newlist2=[]
newlist3=[] #empty list to put both new lists which will have proudcts in them
while i==0:
a=0
while a<len(l[i]):
prod=l[i][a]*l2[i][a] #corresponding product of lists elements
newlist.append(prod) #adding the products to new list
a+=1
i+=1
while i==1:
a=0
while a<len(l[i]):
prod=l[i][a]*l2[i][a] #corresponding product of lists elements
newlist2.append(prod) #adding the products to new list
a+=1
i+=1
newlist3.append(newlist)
newlist3.append(newlist2)
print newlist3

#2 dimensional list example
list1=[[2,3,5,6,7],[5,2,9,3,7]]
list2=[[5,2,9,3,7],[1,3,5,2,2]]
ElementwiseProduct(list1,list2)

Answer

You can zip the two lists in a list comprehension, then further zip the resulting sublists and then finally multiply the items:

list2 = [[5,2,9,3,7],[1,3,5,2,2]]
list1 = [[2,3,5,6,7],[5,2,9,3,7]]

result = [[a*b for a, b in zip(i,j)] for i, j in zip(list1, list2)]
print(result)
# [[10, 6, 45, 18, 49], [5, 6, 45, 6, 14]]

Should in case the lists/sublists do not have the same number of elements, itertools.izip_longest can be used to generate fill values such as an empty sublist for the smaller list, or 0 for the shorter sublist:

from itertools import izip_longest

list1 = [[2,3,5,6]]
list2 = [[5,2,9,3,7],[1,3,5,2,2]]
result = [[a*b for a, b in izip_longest(i,j, fillvalue=0)] 
               for i, j in izip_longest(list1, list2, fillvalue=[])]
print(result)
# [[10, 6, 45, 18, 0], [0, 0, 0, 0, 0]]

You may change the inner fillvalue from 0 to 1 to return the elements in the longer sublists as is, instead of a homogeneous 0.


Reference:

List comprehensions

Comments