【问题标题】:Turning this simple block to idiomatic Python code将这个简单的块转换为惯用的 Python 代码
【发布时间】:2013-01-19 04:17:06
【问题描述】:
def run(first, second):
    sum=[]
    for i in range(len(first)):
        third.append(second[i]+first[i])
    return sum

print run([1,2,3],[10,20,30])

代码运行良好,并打印出一个包含三个元素的列表,其中每个元素是“第二”和“第一”中相同索引的两个元素的总和,特别是[11, 22, 33]。有没有更直接的方法来返回相同的结果?

【问题讨论】:

    标签: python list python-2.7 idioms


    【解决方案1】:

    另一种方法是使用map - 尽管在处理不同的列表长度时注意到zip 和map 之间的区别很有趣。

    我认为在大多数情况下@Marijn Pieters zip 解决方案会满足您的需求,因为zip 在处理列表时更加可爱和柔和。

    In [414]: first = [1,2,3]
    In [415]: second = [10,20,30]
    In [416]: [a + b for a, b in zip(first, second)]
    Out[416]: [11, 22, 33]
    
    In [417]: import operator
    In [418]: map(operator.add, first, second)
    Out[418]: [11, 22, 33]
    
    In [419]: second = [10,20,30,40]
    In [420]: [a + b for a, b in zip(first, second)]
    Out[420]: [11, 22, 33]
    
    In [421]: map(operator.add, first, second)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-421-dd15f26f1e89> in <module>()
    ----> 1 map(operator.add, first, second)
    
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    
    In [422]: map(None, first, second)
    Out[422]: [(1, 10), (2, 20), (3, 30), (None, 40)]
    

    【讨论】:

      【解决方案2】:

      Martijn 发布的最简单的选项:

      def run(a, b):
          return [x + y for x, y in zip(a, b)]
      

      一个可能的改进是让它适用于任意数量的列表,而不仅仅是两个:

      def run(*args):
          return [sum(p) for p in zip(*args)]
      

      另一种概括是允许其他运算符:

      def run(func, *args):
          return map(func, *args)
      

      然后,例如:

      import operator
      
      print run(operator.add, [1,2,3],[10,20,30])  # [11, 22, 33]
      print run(operator.sub, [1,2,3],[10,20,30])  # [-9, -18, -27]
      

      请注意,在所有这三种情况下,run 作为单独的函数是不必要的,可以简单地替换为内置调用。

      【讨论】:

        【解决方案3】:

        并且只是指出另一种方式,它绕过 zip,但确实引入了 map...(有些人觉得可读性较差或不喜欢...)

        from operator import add
        third = map(add, first, second)
        

        【讨论】:

        • 请注意,在 Python > 3 中,这不会像您认为的那样做...而不是 third 是一个列表,而是一个生成器。您需要将 RHS 包装在 list() 中以获得真实列表。
        【解决方案4】:

        您可以使用内置函数map、sum 和zip:

        >>> map(sum, zip([1, 2, 3], [10, 20,30]))
        [11, 22, 33]
        

        【讨论】:

          【解决方案5】:

          当然,使用zip() built-in function 和list comprehension:

          def run(first, second):
              return [a + b for a, b in zip(first, second)]
          

          演示:

          >>> def run(first, second):
          ...     return [a + b for a, b in zip(first, second)]
          ... 
          >>> print run([1,2,3],[10,20,30])
          [11, 22, 33]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-03
            相关资源
            最近更新 更多