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.
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:
[[2,3,5,6,7],[5,2,9,3,7]]
[[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 e.g. 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)
答案 0 :(得分:6)
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:
答案 1 :(得分:2)
这是一个可以处理任何类型的iterable的函数,嵌套到任何级别(任意数量的维度,而不仅仅是2):
def elementwiseProd(iterA, iterB):
def multiply(a, b):
try:
iter(a)
except TypeError:
# You have a number
return a * b
return elementwiseProd(a, b)
return [multiply(*pair) for pair in zip(iterA, iterB)]
此函数递归工作。对于列表中的每个元素,它检查元素是否可迭代。如果是,则输出元素是包含迭代的元素乘法的列表。如果没有,则返回数字的乘积。
此解决方案适用于混合嵌套类型。这里做出的一些假设是,所有嵌套级别都是相同的大小,并且一个可迭代的数字元素(相对于嵌套的可迭代)在另一个中始终是一个数字。
事实上,这个代码片段可以扩展为将任何n元函数应用于任何n个迭代:
def elementwiseApply(op, *iters):
def apply(op, *items):
try:
iter(items[0])
except TypeError:
return op(*items)
return elementwiseApply(op, *items)
return [apply(op, *items) for items in zip(*iters)]
要进行乘法运算,您可以使用operator.mul
:
from operator import mul
list1=[[2,3,5,6,7], [5,2,9,3,7]]
list2=[[5,2,9,3,7], [1,3,5,2,2]]
elementwiseApply(mul, list1, list2)
产生
[[10, 6, 45, 18, 49], [5, 6, 45, 6, 14]]
答案 2 :(得分:1)
在Python中,通常最好直接循环遍历列表中的项目,而不是使用索引间接循环。它使代码更容易阅读,也更有效,因为它避免了繁琐的索引算法。
以下是使用传统for
循环解决问题的方法。我们使用内置的zip
函数同时迭代两个(或更多)列表。
def elementwise_product(list1,list2):
result = []
for seq1, seq2 in zip(list1,list2):
prods = []
for u, v in zip(seq1, seq2):
prods.append(u * v)
result.append(prods)
return result
list1=[[2,3,5,6,7], [5,2,9,3,7]]
list2=[[5,2,9,3,7], [1,3,5,2,2]]
print(elementwise_product(list1,list2))
<强>输出强>
[[10, 6, 45, 18, 49], [5, 6, 45, 6, 14]]
我们可以使用list comprehensions使代码更紧凑。一开始看起来似乎比较难读,但你会习惯用练习来列出理解。
def elementwise_product(list1,list2):
return [[u*v for u, v in zip(seq1, seq2)]
for seq1, seq2 in zip(list1,list2)]
答案 3 :(得分:-1)
You could use numpy arrays. They are your best option as they run on a C background and hence are much faster computationally
First, install numpy. Shoot up your terminal (CMD if you're in windows), type
pip install numpy
or, if in Linux, sudo pip install numpy
Then, go on to write your code
import numpy as np
list1=np.array([[2,3,5,6,7],[5,2,9,3,7]]) #2 dimensional list example
list2=np.array([[5,2,9,3,7],[1,3,5,2,2]])
prod = np.multiply(list1,list2)
# or simply, as suggested by Mad Physicist,
prod = list1*list2