【问题标题】:Passing generator vs list for Python any为 Python any 传递生成器 vs 列表
【发布时间】:2016-03-04 06:56:46
【问题描述】:

给定一个整数列表,例如integers = [1, 2, 3, 4, 5, 6]

我想知道使用 Python 的 any() 函数列表中是否有偶数。我的问题是,像这样传递列表理解结果是否更有效:

evens = [each for each in integers if each % 2 == 0]
has_even = any(evens)

相对于使用生成器,例如:

has_even = any(each for each in integers if each % 2 == 0)

【问题讨论】:

    标签: python


    【解决方案1】:

    最好将生成器传递给any 和all,而不是将列表推导式传递给all。这两个函数都可以短路,即any 将在遇到True 值时停止,all 将在遇到False 值时停止。如果您向他们传递列表理解,则必须在 any / all 开始工作之前构建整个列表,但如果您向他们传递生成器,则只会生成所需的值。因此,使用生成器不仅可以节省 RAM,还可以节省大量的执行时间。

    您的生成器可以变得更高效; if 部分是多余的。

    has_even = any(each % 2 == 0 for each in integers)
    

    【讨论】:

      【解决方案2】:

      any 使用生成器是这里最有效的方法,因为它不会分配所有偶数的列表,而且它会在第一个偶数处停止,甚至不考虑其他偶数。输入也可以是生成器(例如,从文件中读取数字),在这种情况下,如果您停止读取输入,节省会更大。

      带有生成器的any 也非常易读,尤其是如果您定义了even 谓词...

      def even(x):
          return x % 2 == 0
      
      if any(even(x) for x in integers):
          ...
      

      可读性应该是您最关心的大多数软件(当今的计算机通常都非常快)。

      如果你的眼睛是用函数式方法训练的,那么一个更易读的版本可能是

      if any(filter(even, integers)):
         ...
      

      使用 Python 3 也同样有效(一旦知道结果,就不会从 numbers 提取输入)。

      但是请注意,如果这种计算的效率是您最关心的问题,那么 Python 可能是错误的工具...

      【讨论】:

        猜你喜欢
        • 2019-11-24
        • 2014-04-02
        • 2017-10-04
        • 2013-06-30
        • 2020-05-16
        • 2016-08-14
        • 1970-01-01
        • 2015-07-06
        • 1970-01-01
        相关资源
        最近更新 更多