【问题标题】:Element-wise product of two 2-D lists两个二维列表的元素乘积
【发布时间】:2017-03-02 12:24:33
【问题描述】:

我不能使用 Numpy 或任何其他库函数,因为这是我必须做的问题,我必须定义自己的方式。

我正在编写一个将两个列表(二维)作为参数的函数。该函数应该计算两个列表的元素乘积并将它们存储在第三个列表中,并从函数返回这个结果列表。 输入列表的一个示例是:

列表1:

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

列表2:

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

该函数打印以下列表:

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

2*5=103*2=65*9=45 ...等等。

这是我下面的代码,但它仅适用于其中包含 2 个列表(元素)的列表,就像上面的示例一样,并且工作得非常好,但我想要的是编辑我的代码,以便无论如何二维列表中有许多列表(元素),它应该在新的二维列表中打印出其元素乘积,例如它也应该适用于

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

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

或整个列表中有任意数量的列表。

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)

【问题讨论】:

  • 你应该在列表中使用 zip
  • Moses Koledoye 的回答应该可以在没有 Numpy 的情况下解决问题
  • 如果以下答案之一解决了您的问题,您应该接受它(单击相应答案旁边的复选标记)。这有两件事。它让每个人都知道您的问题已得到您满意的解决,并为帮助您的人提供帮助。有关完整说明,请参阅here

标签: python list python-2.7


【解决方案1】:

你可以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]]

如果 lists/sublists 的元素数量不同,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]]

您可以将内部 fillvalue 从 0 更改为 1,以按原样返回较长子列表中的元素,而不是同质的 0。


参考

List comprehensions

【讨论】:

  • 你也可以用result = [[a*b for a, b in zip(*e)] for e in zip(list1, list2)]引入参数扩展
  • @MadPhysicist 这看起来更整洁,但需要一些关于解包如何工作的解释:)
  • 添加reduceoperator.mul的使用,这个答案是金
【解决方案2】:

这是一个函数,可以处理任何类型的可迭代,嵌套到任何级别(任何维数,而不仅仅是 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)]

这个函数递归地工作。对于列表中的每个元素,它检查该元素是否是可迭代的。如果是,则输出元素是一个列表,其中包含可迭代的元素乘法。如果不是,则返回数字的乘积。

此解决方案适用于混合嵌套类型。这里做了几个假设,即所有嵌套级别的大小相同,并且一个可迭代对象(与嵌套可迭代对象)中的数字元素始终是另一个可迭代对象中的数字。

事实上,这个 sn-p 可以扩展为将任何 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]]

【讨论】:

  • 可爱,但我怀疑它对于 OP 来说可能有点太高级了。 OTOH,其他读者可能会感兴趣。
  • @PM2Ring。当我认为它看起来需要处理任何维数组时,我写了回来。保留它是出于您所说的确切原因。不要指望它是公认的答案,但它是一个有用的例子。
【解决方案3】:

在 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)]

【讨论】:

  • 我喜欢这个答案,因为它解决了 OP 代码的最基本问题。对于刚接触 Python 的人来说,这可能是最有帮助的。
【解决方案4】:

您可以使用 numpy 数组。它们是您的最佳选择,因为它们在 C 背景上运行,因此计算速度要快得多

首先,安装 numpy.打开你的终端(如果你在 Windows 中,请输入 CMD),输入

pip install numpy

或者,如果在 Linux 中,sudo pip install numpy

然后,继续编写你的代码

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

【讨论】:

  • 希望您不介意导入编辑。 OP 对 Python 来说似乎很新,所以最好是明确的。
  • 另外,你也可以list1 * list2
  • 你还必须安装 numpy. OP 还负责编写自己的函数,因此根据他们问题的第一行,numpy 不是一个选项。我不能使用 numpy ....
  • 感谢您指出@PadraicCunningham。添加了安装指南。 Numpy 是一个必不可少的库,所以我认为他应该尝试一下。
  • 还有@MadPhysicist 感谢您的提醒:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
  • 2020-07-18
相关资源
最近更新 更多