简体   繁体   English

Python 是否在每个步骤中计算列表理解条件?

[英]Does Python calculate list comprehension condition in each step?

In a list comprehension with a condition that has a function call in it, does Python (specifically CPython 3.9.4) call the function each time, or does it calculate the value once and then uses it?在具有 function 调用的条件的列表理解中,Python(特别是 CPython 3.9.4)调用 ZC1C425268E68385D1AB5074C17A94F1 是否每次都计算值,然后使用它?

For example if you have:例如,如果您有:

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)]

Will Python actually calculate the np.average(list_1) len(list_1) times? Python 会实际计算np.average(list_1) len(list_1)次吗? So would it be more optimized to write那么写起来会不会更优化

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]

instead?反而? Or does Python already "know" to just calculate the average beforehand?还是 Python 已经“知道”预先计算平均值?

Python has to call the function each time. Python 每次必须调用 function。 It cannot optimize that part, because successive calls of the function might return different results (for example because of side effects).它无法优化该部分,因为 function 的连续调用可能会返回不同的结果(例如,由于副作用)。 There is no easy way for Python's compiler to be sure that this can't happen. Python 的编译器没有简单的方法来确保这不会发生。

Therefore, if you (the programmer) know that the result will always be the same – like in this case – it is probably advisable to calculate the result of the function in advance and use it inside the list comprehension.因此,如果您(程序员)知道结果总是相同的——就像在这种情况下——最好提前计算 function 的结果并在列表推导中使用它。

Assuming standard CPython - Short answer: Yes.假设标准 CPython - 简短回答:是的。 Your second snippet is more efficient.您的第二个片段更有效。

A function call in the filter part of a list comprehension will be called for each element.将为每个元素调用列表推导的过滤器部分中的 function 调用。

We can test this quite easily with a trivial example:我们可以用一个简单的例子很容易地对此进行测试:

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

The above is somewhat equivalent to doing:上面有点等价于做:

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

Since you're comparing against the same average each time, you can indeed just calculate it beforehand and use the same value as you did in your second code snippet.由于您每次都在与相同的平均值进行比较,因此您确实可以预先计算它并使用与第二个代码片段中相同的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM