简体   繁体   English

两个二维列表的元素乘积

[英]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. 我不能使用Numpy或任何其他库函数,因为这是我必须要做的一个问题,我必须定义自己的方式。

I am writing a function that takes two lists (2 dimensional) as arguments. 我正在编写一个函数,它将两个列表(2维)作为参数。 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: 列表1:

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

list2: 列表2:

[[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. 那是2*5=10 3*2=6 5*9=45 ......依此类推。

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 这是我的下面的代码,但它只适用于里面有2个列表(元素)的列表,就像上面的例子一样,并且完全可以正常工作,但我想要的是编辑我的代码,这样无论有多少个列表(元素)存在于二维列表中,它应该在一个新的二维列表中打印出它的元素产品,例如它也应该适用于

[[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)

You can zip the two lists in a list comprehension , then further zip the resulting sublists and then finally multiply the items: 您可以zip这两个列表列表中的理解 ,则进一步zip所产生的子表 ,然后最后乘以项目:

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: 如果列表 / 子列表没有相同数量的元素,则itertools.izip_longest可用于生成填充值,例如较小列表的空子列表,或较短子列表的0:

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. 您可以将内部fillvalue从0更改为1,以按fillvalue返回较长子列表中的元素,而不是同类0。


Reference : 参考

List comprehensions 列表理解

Here is a function that can handle any type of iterable, nested to any level (any number of dimensions, not just 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)]

This function works recursively. 此函数递归工作。 For each element in a list, it checks if the element is iterable. 对于列表中的每个元素,它检查元素是否可迭代。 If it is, the output element is a list containing the elementwise multiplication of the iterables. 如果是,则输出元素是包含迭代的元素乘法的列表。 If not, the product of the numbers is returned. 如果不是,则返回数字的乘积。

This solution will work on mixed nested types. 此解决方案适用于混合嵌套类型。 A couple of assumptions that are made here are that all the levels of nesting are the same size, and that an element that is a number in one iterable (vs a nested iterable), is always a number in the other. 这里做出的一些假设是,所有嵌套级别都是相同的大小,并且一个迭代中的数字元素(相对于嵌套的可迭代)始终是另一个中的数字。

In fact, this snippet can be extended to apply any n-ary function to any n iterables: 事实上,这个代码片段可以扩展为将任何n-ary函数应用于任何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)]

To do multiplication, you would use operator.mul : 要进行乘法运算,您可以使用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)

produces 产生

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

In Python, it's generally better to loop directly over the items in a list, rather than looping indirectly using indices. 在Python中,通常最好直接循环遍历列表中的项,而不是使用索引间接循环。 It makes the code easier to read as well as more efficient since it avoids the tedious index arithmetic. 它使代码更容易阅读,也更有效,因为它避免了繁琐的索引算法。

Here's how to solve your problem using traditional for loops. 以下是使用传统for循环解决问题的方法。 We use the built-in zip function to iterate over two (or more) lists simultaneously. 我们使用内置的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))

output 产量

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

We can use list comprehensions to make that code a lot more compact. 我们可以使用列表推导来使代码更紧凑。 It may seem harder to read at first, but you'll get used to list comprehensions with practice. 一开始看起来可能看起来更难,但你会习惯用练习列出理解。

def elementwise_product(list1,list2):
    return [[u*v for u, v in zip(seq1, seq2)] 
        for seq1, seq2 in zip(list1,list2)]

You could use numpy arrays. 你可以使用numpy数组。 They are your best option as they run on a C background and hence are much faster computationally 它们是您最好的选择,因为它们在C背景上运行,因此计算速度更快

First, install numpy. 首先,安装numpy。 Shoot up your terminal (CMD if you're in windows), type 点击您的终端(如果您在窗口中,则为CMD),键入

pip install numpy

or, if in Linux, sudo pip install numpy 或者,如果在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM