【问题标题】:Subtracting 2 lists in Python在 Python 中减去 2 个列表
【发布时间】:2009-02-10 23:57:22
【问题描述】:

现在我将 vector3 值表示为列表。有没有办法减去其中的 2 个,比如 vector3 值,比如

[2,2,2] - [1,1,1] = [1,1,1]

我应该使用元组吗?

如果它们都没有在这些类型上定义这些操作数,我可以定义它吗?

如果没有,我应该创建一个新的 vector3 类吗?

【问题讨论】:

    标签: python list tuples vector


    【解决方案1】:

    如果这是你经常做的事情,并且有不同的操作,你可能应该创建一个类来处理这样的情况,或者更好地使用像Numpy这样的库。

    否则,查找与zip 内置函数一起使用的list comprehensions

    [a_i - b_i for a_i, b_i in zip(a, b)]
    

    【讨论】:

      【解决方案2】:

      已经提出了许多解决方案。

      如果对速度感兴趣,这里是关于速度的不同解决方案的回顾(从最快到最慢)

      import timeit
      import operator
      
      a = [2,2,2]
      b = [1,1,1]  # we want to obtain c = [2,2,2] - [1,1,1] = [1,1,1
      
      %timeit map(operator.sub, a, b)
      176 ns ± 7.18 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit map(int.__sub__, a, b)
      179 ns ± 4.95 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit map(lambda x,y: x-y, a,b)
      189 ns ± 8.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit [a_i - b_i for a_i, b_i in zip(a, b)]
      421 ns ± 18.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit [x - b[i] for i, x in enumerate(a)]
      452 ns ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each
      
      %timeit [a[i] - b[i] for i in range(len(a))]
      530 ns ± 16.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit list(map(lambda x, y: x - y, a, b))
      546 ns ± 16.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      %timeit np.subtract(a,b)
      2.68 µs ± 80.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      %timeit list(np.array(a) - np.array(b))
      2.82 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      %timeit np.matrix(a) - np.matrix(b)
      12.3 µs ± 437 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      

      使用map 显然是最快的。 令人惊讶的是,numpy 是最慢的。事实证明,首先将列表 ab 转换为 numpy 数组的成本是一个瓶颈,它超过了矢量化带来的任何效率提升。

      %timeit a = np.array([2,2,2]); b=np.array([1,1,1])
      1.55 µs ± 54.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      
      a = np.array([2,2,2])
      b = np.array([1,1,1])
      %timeit a - b
      417 ns ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
      

      【讨论】:

        【解决方案3】:
        import numpy as np
        a = [2,2,2]
        b = [1,1,1]
        np.subtract(a,b)
        

        【讨论】:

          【解决方案4】:

          如果你的列表是 a 和 b,你可以这样做:

          map(int.__sub__, a, b)
          

          但您可能不应该这样做。没有人会知道这意味着什么。

          【讨论】:

          • 我自己用花车碰到了这个。在这种情况下map(float.__sub__, a, b) 有效。感谢您的提示!
          • 嗨,比import operator map(operator.sub, a, b)快吗?
          • recursive:我实际上想使用它,所以我只是在 LOCAL 范围内使用“subtract = int.__sub__”为它起别名,以避免引入“operator”并使其清晰可读。我真的不认为这样不好。 @zheyuanWang 充其量只是稍微快一点。我没有做真正的计时,但在 leetcode 上解决了一个问题,它和其他任何东西一样快,也许快一点(但这些数字跳跃很多。)
          【解决方案5】:

          这是列表推导的替代方法。 Map 遍历列表(后面的参数),同时进行,并将它们的元素作为参数传递给函数(第一个参数)。它返回结果列表。

          import operator
          map(operator.sub, a, b)
          

          这段代码因为语法较少(这对我来说更美观),而且显然它对于长度为 5 的列表快 40%(参见 bobince 的评论)。不过,任何一种解决方案都可以。

          【讨论】:

          • 我通常会在 map() 上看到列表推导被推荐,尽管这可能只是因为它的代码看起来更简洁......不确定性能差异(如果有的话)。
          • 对于我来说,在 Py2.6 上,对于五元素减法,map() 的输出速度快了近 40%。在避免 lambda 的情况下,理解更新更清晰,但对于映射现有函数,map 仍然很漂亮……尤其是在这里您可以利用内置 zip。
          • 这也适用于array.array(虽然结果是一个列表)
          • 需要'import operator'子句; int.__sub__ 做得更好))
          • 为了打印内容你可以写print(list(map(operator.sub, a, b)))
          【解决方案6】:

          我也必须推荐NumPy

          它不仅可以更快地进行矢量数学运算,而且还具有大量便利功能。

          如果您想要更快的一维向量,请尝试vop

          它类似于 MatLab,但免费。这是一个你会做什么的例子

          from numpy import matrix
          a = matrix((2,2,2))
          b = matrix((1,1,1))
          ret = a - b
          print ret
          >> [[1 1 1]]
          

          轰隆隆。

          【讨论】:

          • np.array 会是一个更简单的解决方案
          【解决方案7】:

          对于曾经在 Pycharm 上编写代码的人来说,它也可以让其他人恢复活力。

           import operator
           Arr1=[1,2,3,45]
           Arr2=[3,4,56,78]
           print(list(map(operator.sub,Arr1,Arr2)))
          

          【讨论】:

            【解决方案8】:

            Python中maplambda函数的组合很好的解决了这类问题:

            a = [2,2,2]
            b = [1,1,1]
            map(lambda x,y: x-y, a,b)
            

            zip 函数是另一个不错的选择,正如@UncleZeiv 所展示的那样

            【讨论】:

              【解决方案9】:

              这个答案展示了如何编写“正常/易于理解”的 Python 代码。

              我建议不要使用zip,因为并不是每个人都知道它。


              解决方案使用list comprehensions 和常用的内置函数。


              备选方案 1(推荐):

              a = [2, 2, 2]
              b = [1, 1, 1]
              result = [a[i] - b[i] for i in range(len(a))]
              

              推荐,因为它只使用 Python 中最基本的函数


              备选方案 2:

              a = [2, 2, 2]
              b = [1, 1, 1]
              result = [x - b[i] for i, x in enumerate(a)]
              

              备选方案 3(如 BioCoder 所述):

              a = [2, 2, 2]
              b = [1, 1, 1]
              result = list(map(lambda x, y: x - y, a, b))
              

              【讨论】:

                【解决方案10】:

                如果您有两个名为“a”和“b”的列表,您可以这样做:[m - n for m,n in zip(a,b)]

                【讨论】:

                  【解决方案11】:

                  一个略有不同的 Vector 类。

                  class Vector( object ):
                      def __init__(self, *data):
                          self.data = data
                      def __repr__(self):
                          return repr(self.data) 
                      def __add__(self, other):
                          return tuple( (a+b for a,b in zip(self.data, other.data) ) )  
                      def __sub__(self, other):
                          return tuple( (a-b for a,b in zip(self.data, other.data) ) )
                  
                  Vector(1, 2, 3) - Vector(1, 1, 1)
                  

                  【讨论】:

                    【解决方案12】:

                    如果您计划执行的不仅仅是简单的单行,最好实现自己的类并覆盖适用于您的案例的适当运算符。

                    取自Mathematics in Python

                    class Vector:
                    
                      def __init__(self, data):
                        self.data = data
                    
                      def __repr__(self):
                        return repr(self.data)  
                    
                      def __add__(self, other):
                        data = []
                        for j in range(len(self.data)):
                          data.append(self.data[j] + other.data[j])
                        return Vector(data)  
                    
                    x = Vector([1, 2, 3])    
                    print x + x
                    

                    【讨论】:

                      【解决方案13】:
                      arr1=[1,2,3]
                      arr2=[2,1,3]
                      ls=[arr2-arr1 for arr1,arr2 in zip(arr1,arr2)]
                      print(ls)
                      >>[1,-1,0]
                      

                      【讨论】:

                      • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
                      【解决方案14】:

                      很简单

                      list1=[1,2,3,4,5]
                      list2=[1,2]
                      list3=[]
                      # print(list1-list2)
                      
                      for element in list1:
                          if element not in list2:
                             list3.append(element)
                      
                      print(list3)
                      

                      【讨论】:

                        【解决方案15】:

                        使用 for 循环

                        a = [3,5,6]
                        b = [3,7,2]
                        
                        c = []
                        
                        for i in range(len(a)):
                             c.append(a[i] - b[i])
                        
                        print(c)
                        

                        输出 [0, -2, 4]

                        【讨论】:

                          【解决方案16】:

                          试试这个:

                          list(array([1,2,3])-1)
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-09-29
                            • 1970-01-01
                            • 2018-01-30
                            • 1970-01-01
                            • 2023-02-14
                            • 1970-01-01
                            相关资源
                            最近更新 更多