【问题标题】:How to perform element-wise multiplication of two lists?如何执行两个列表的元素乘法?
【发布时间】:2012-05-03 12:42:56
【问题描述】:

我想执行元素乘法,在 Python 中将两个列表按值相乘,就像我们可以在 Matlab 中那样。

这就是我在 Matlab 中的做法。

a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]

对于来自axx * y 和来自by 的每个组合,列表解析将给出16 个列表条目。不确定如何映射。

如果有人对为什么感兴趣,我有一个数据集,想将其乘以 Numpy.linspace(1.0, 0.5, num=len(dataset)) =)

【问题讨论】:

  • 为什么你现在已经问这个关于 numpy 的问题了?
  • 顺便说一下,这是逐元素乘法,这不是点积。
  • 替代方案:map(lambda x, y: x*y, list1, list2) #derp...

标签: python list multiplication elementwise-operations


【解决方案1】:

使用与zip(): 混合的列表理解。

[a*b for a,b in zip(lista,listb)]

【讨论】:

  • 另一方面,如果他们想在此处的琐碎案例之外做任何其他事情,那么建议 OP 使用 Numpy。
  • 在 Python 2 上 izip() 可能是更好的选择。
  • 你也可以使用map(lambda x,y:x*y,lista,listb)
  • 如果我们给出的是listb而不是listb类型的元素列表,答案将如何变化,我们需要操作以获得单个列表。前任。 (x, pi, e) 与 [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)],取 (x, pi, e) 与 (4, 5, 2) 一起操作,然后 (x, pi, e) 与 (1, 2, 4) 一起操作 ... 以此类推。
  • @gxyd 你应该问一个单独的问题
【解决方案2】:

由于您已经在使用numpy,因此将数据存储在numpy 数组而不是列表中是有意义的。完成此操作后,您将免费获得诸如元素产品之类的东西:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: b = np.array([2,3,4,5])

In [4]: a * b
Out[4]: array([ 2,  6, 12, 20])

【讨论】:

  • 也许不是最科学的,但我使用 timeit 对 gahooa 的答案进行了计时。 Numpy 实际上比 zip 方法稍慢。
  • 在我的例子中,列表包含二进制值,numpy 解决方案比使用 izip 快得多。
  • 为了其他人从谷歌搜索到达这里的利益,我在下面提供了一个时间比较。
【解决方案3】:

使用 np.multiply(a,b):

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)

【讨论】:

    【解决方案4】:

    您可以尝试在循环中将每个元素相乘。这样做的捷径是

    ab = [a[i]*b[i] for i in range(len(a))]
    

    【讨论】:

    • 欢迎来到stackoverflow!通常不鼓励仅使用代码的答案 - 请添加一些关于如何解决提问者问题的解释。
    • @CorleyBrigman 我不同意;答案是“这是一种方法:”和“”之间几乎没有区别。在这种特殊情况下,除了“此代码解决了您的问题”之外,几乎没有什么可解释的。
    • @CorleyBrigman 我不同意;显示结果的示例数据实际上会更有帮助
    • 这就是作为 Python 新手的 C、C++ 或 Java 程序员解决问题的方法。 accepted answer 是惯用的 Python。
    • @Tjorriemorrie 结果很清楚,因为它们在问题中明确要求。也许对列表推导如何工作的解释可能会很好,或者提到这利用了列表推导,然后每个人都可以查看它,如果他们不知道的话。
    【解决方案5】:

    又一个答案:

    -1 ... 需要导入
    +1 ... 可读性很强

    import operator
    a = [1,2,3,4]
    b = [10,11,12,13]
    
    list(map(operator.mul, a, b))
    

    输出 [10, 22, 36, 52]

    【讨论】:

    • 如果您知道地图,这是一个非常易读的解决方案!除了位于文件顶部之外,导入是否有任何负面影响? (编辑可以根据需要隐藏导入)据我所知,它应该在每个 python 2 和 3 版本中都可用!
    • 非常好的功能解决方案!
    【解决方案6】:

    非常直观的做法:

    a = [1,2,3,4]
    b = [2,3,4,5]
    ab = []                        #Create empty list
    for i in range(0, len(a)):
         ab.append(a[i]*b[i])      #Adds each element to the list
    

    【讨论】:

      【解决方案7】:

      你可以使用lambda进行乘法

      foo=[1,2,3,4]
      bar=[1,2,5,55]
      l=map(lambda x,y:x*y,foo,bar)
      

      【讨论】:

        【解决方案8】:

        对于大型列表,我们可以使用迭代方式:

        product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])
        

        product_iter_object.next() 给出输出列表中的每个元素。

        输出将是两个输入列表中较短者的长度。

        【讨论】:

          【解决方案9】:

          创建一个数组; 将每个列表乘以数组; 将数组转换为列表

          import numpy as np
          
          a = [1,2,3,4]
          b = [2,3,4,5]
          
          c = (np.ones(len(a))*a*b).tolist()
          
          [2.0, 6.0, 12.0, 20.0]
          

          【讨论】:

            【解决方案10】:

            gahooa 对标题中的问题的回答是正确的,但如果列表已经是 numpy 格式 大于 10,它会快得多(3 个订单数量级)以及更具可读性,可以按照 NPE 的建议进行简单的 numpy 乘法。我得到了这些时间:

            0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
            0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
            0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
            0.0013ms -> N = 4, a = np.arange(N), c = a * b
            0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
            0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
            0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
            0.0013ms -> N = 40, a = np.arange(N), c = a * b
            0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
            0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
            1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
            0.0020ms -> N = 400, a = np.arange(N), c = a * b
            

            即来自以下测试程序。

            import timeit
            
            init = ['''
            import numpy as np
            N = {}
            a = {}
            b = np.linspace(0.0, 0.5, len(a))
            '''.format(i, j) for i in [4, 40, 400] 
                              for j in ['[i for i in range(N)]', 'np.arange(N)']]
            
            func = ['''c = [a*b for a,b in zip(a, b)]''',
            '''c = a * b''']
            
            for i in init:
              for f in func:
                lines = i.split('\n')
                print('{:6.4f}ms -> {}, {}, {}'.format(
                       timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))
            

            【讨论】:

              【解决方案11】:

              可以使用枚举。

              a = [1, 2, 3, 4]
              b = [2, 3, 4, 5]
              
              ab = [val * b[i] for i, val in enumerate(a)]
              

              【讨论】:

                【解决方案12】:

                map 函数在这里非常有用。 使用map,我们可以将任何函数应用于迭代的每个元素。

                Python 3.x

                >>> def my_mul(x,y):
                ...     return x*y
                ...
                >>> a = [1,2,3,4]
                >>> b = [2,3,4,5]
                >>>
                >>> list(map(my_mul,a,b))
                [2, 6, 12, 20]
                >>>
                

                当然:

                map(f, iterable)
                

                等价于

                [f(x) for x in iterable]
                

                所以我们可以通过以下方式获得我们的解决方案:

                >>> [my_mul(x,y) for x, y in zip(a,b)]
                [2, 6, 12, 20]
                >>>
                

                在 Python 2.x 中map() 意味着:将一个函数应用于一个可迭代对象的每个元素并构造一个新列表。 在 Python 3.x 中,map 构造迭代器而不是列表。

                我们可以使用mul 运算符来代替my_mul

                Python 2.7

                >>>from operator import mul # import mul operator
                >>>a = [1,2,3,4]
                >>>b = [2,3,4,5]
                >>>map(mul,a,b)
                [2, 6, 12, 20]
                >>>
                

                Python 3.5+

                >>> from operator import mul
                >>> a = [1,2,3,4]
                >>> b = [2,3,4,5]
                >>> [*map(mul,a,b)]
                [2, 6, 12, 20]
                >>>
                

                请注意,由于map() 构造了一个迭代器,我们使用* 可迭代解包运算符来获取一个列表。 解包方法比 list 构造函数快一点:

                >>> list(map(mul,a,b))
                [2, 6, 12, 20]
                >>>
                

                【讨论】:

                  【解决方案13】:

                  要维护列表类型,并在一行中完成(当然是在将 numpy 导入为 np 之后):

                  list(np.array([1,2,3,4]) * np.array([2,3,4,5]))
                  

                  list(np.array(a) * np.array(b))
                  

                  【讨论】:

                    【解决方案14】:

                    您可以将其用于相同长度的列表

                    def lstsum(a, b):
                        c=0
                        pos = 0
                    for element in a:
                       c+= element*b[pos]
                       pos+=1
                    return c
                    

                    【讨论】:

                      【解决方案15】:
                      import ast,sys
                      input_str = sys.stdin.read()
                      
                      input_list = ast.literal_eval(input_str)
                      
                      list_1 = input_list[0]
                      
                      list_2 = input_list[1]
                      
                      import numpy as np
                      
                      array_1 = np.array(list_1)
                      
                      array_2 = np.array(list_2)
                      
                      array_3 = array_1*array_2
                      
                      
                      print(list(array_3))
                      

                      【讨论】:

                      • 虽然此代码可能会解决问题,但 including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。 From Review
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-03-02
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-12-16
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多