Python 是否计算每一步的列表理解条件?



在具有函数调用的条件的列表推导式中,Python(特别是CPython 3.9.4)是每次都调用该函数,还是计算一次值然后使用它?

例如,如果您有:

list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
list_2 = [x for x in list_1 if x > np.average(list_1)]

Python真的会计算np.average(list_1)len(list_1)次吗?那么写会更优化吗

list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
np_avg = np.average(list_1)
list_2 = [x for x in list_1 if x > np_avg]

相反?还是Python已经"知道"事先计算平均值?

Python每次都必须调用该函数。它无法优化该部分,因为函数的连续调用可能会返回不同的结果(例如,由于副作用)。对于Python的编译器来说,没有简单的方法来确保这不会发生。

因此,如果你(程序员)知道结果总是相同的——就像在这种情况下一样——那么建议提前计算函数的结果,并在列表理解中使用它。

假设标准 CPython - 简短回答:是的。您的第二个代码段效率更高。

将为每个元素调用列表推导式的过滤器部分中的函数调用。

我们可以通过一个微不足道的例子轻松测试这一点:

def f(value):
""" Allow even values only """ 
print('function called')
return value % 2 == 0
mylist = [x for x in range(5) if f(x)]
# 'function called' will be printed 5 times

以上有点等效于做:

mylist = []
for x in range(5):
if f(x):
mylist.append(x)

由于您每次都与相同的平均值进行比较,因此您确实可以事先计算它并使用与第二个代码片段中相同的值。

最新更新