2

我在玩海象运算符(与这个问题有关:=),这将在 python 3.8 中可用。

def f(x):
    return x**3

old_list =  = list(range(9))

这可以按预期工作(不要介意这个例子毫无意义......):

new_list = [fx for x in old_list if (fx := f(x))  in {1, 8, 343}]
# [1, 8, 343]

这是有效的并且可以运行,但是会返回一些意想不到的东西:

new_list = [fx := f(x) for x in old_list if fx in {1, 8, 343}]
# []

这里发生了什么?

4

1 回答 1

4

TL; DR 你的第二个不是“那个”有效的:

>>> old_list = list(range(9))
>>> f = lambda x: x ** 3
>>> [fx := f(x) for x in old_list if fx in {1, 8, 343}]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
NameError: name 'fx' is not defined
>>> 

解释

在您的第一个列表理解中,[fx for x in old_list if (fx := f(x)) in {1, 8, 343}],在fx :=它之外创建一个变量:

>>> old_list = list(range(9))
>>> f = lambda x: x ** 3
>>> [fx for x in old_list if (fx := f(x))  in {1, 8, 343}]
[1, 8, 343]
>>> fx
512

如果你[fx := f(x) for x in old_list if fx in {1, 8, 343}]之后运行,它会像这样:

  • for x in old_list将 x 绑定到 0
  • if fx in {1, 8, 343}, fx 是旧的512,这是错误的
  • 由于 if 为假,“select”(左)部分没有执行,没有调用 f,没有重新绑定 fx,fx 仍然是 512。
  • 将 x 指定为 old_list 的第二个元素,为 1
  • ...

我们可以像这样仔细检查这个解释:

>>> [print("no no no") for x in old_list if fx in {1, 8, 343}]
[]

no no no永远不会被打印,所以这一面永远不会被执行(就像fx512 一样,不在 中set)。

于 2019-07-10T11:48:36.887 回答