【问题标题】:Python walrus operator fails within rangePython 海象运算符在范围内失败
【发布时间】:2020-04-09 16:05:07
【问题描述】:

为什么我可以使用类似的东西

import numpy as np

print( (g := np.arange(256)**2) / np.max(g) )

但以下失败了?

foo = list(range(256))
for i in range( (l := len(foo)) // 16 + 0 if l%16 == 0 else 1 ):
    print(i)
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    for i in range( (l := len(foo)) // 16 + 0 if l%16 == 0 else 1 ):
NameError: name 'l' is not defined

【问题讨论】:

  • 你还没有定义l。首先评估 l%16 == 0 失败。

标签: python-3.x operators


【解决方案1】:

在参数列表中,表达式是从左到右计算的,所以在:

plt.plot( range( len( (Y := foo) )), Y )

第一个参数range( len( (Y := foo) )) 在第二个参数Y 之前被评估,因此Y 在Y 被引用为第二个参数之前被定义为foo。

但是,在条件表达式中,if 子句中的表达式在计算任一输出表达式之前计算,因此:

(l := len(foo)) // 16 + 0 if l%16 == 0 else 1

首先评估l%16 == 0,并且由于此时尚未定义l,因此会引发所述NameError。

如果确实是您想要的逻辑,您可以先在if 子句中定义l:

for i in range( l // 16 + 0 if (l := len(foo))%16 == 0 else 1 ):

【讨论】:

  • 那么,赋值表达式总是首先被计算?有没有一种明智的方法来改变评估顺序或使这项工作?
  • 不,我的观点恰恰相反。赋值表达式不会首先被评估,而是遵循运算符优先级的常规顺序。无法更改运算符优先级,因为它是 Python 语法定义的一部分。
  • 对了,我对for i in range( l // 16 + 0 if (l := len(foo))%16 == 0 else 1 ):的建议不是你想要的吗?如果不是,您要寻找的逻辑是什么?
  • 这正是我要找的!非常感谢你!要么我读过它,要么它还没有。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多