为Python传递生成器vs列表

时间:2016-03-04 06:56:46

标签: python

给出一个整数列表,例如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)

2 个答案:

答案 0 :(得分:2)

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

您的发电机可以更高效; if部分是多余的。

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

答案 1 :(得分: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可能是错误的工具......