Python 3.x Python walrus运算符在范围内失败

Python 3.x Python walrus运算符在范围内失败,python-3.x,operators,Python 3.x,Operators,为什么我可以用这样的东西 将numpy导入为np 打印((g:=np.arange(256)**2)/np.max(g)) 但以下方法失败了 foo=list(范围(256)) 对于范围内的i((l:=len(foo))//16+0,如果l%16==0,则为1): 印刷品(一) 回溯(最近一次呼叫最后一次): 文件“test.py”,第8行,在 对于范围内的i((l:=len(foo))//16+0,如果l%16==0,则为1): 名称错误:未定义名称“l” 在参数列表中,表达式从左到右求值

为什么我可以用这样的东西

将numpy导入为np
打印((g:=np.arange(256)**2)/np.max(g))
但以下方法失败了

foo=list(范围(256))
对于范围内的i((l:=len(foo))//16+0,如果l%16==0,则为1):
印刷品(一)
回溯(最近一次呼叫最后一次):
文件“test.py”,第8行,在
对于范围内的i((l:=len(foo))//16+0,如果l%16==0,则为1):
名称错误:未定义名称“l”

在参数列表中,表达式从左到右求值,因此:

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

您尚未定义
l
。首先计算的
l%16==0
失败。那么,赋值表达式总是先计算吗?有没有一种合理的方法来改变评估顺序或使其发挥作用?没有,我的观点恰恰相反。赋值表达式不会首先求值,而是遵循运算符优先级的常规顺序。无法更改运算符优先级,因为它是Python语法定义的一部分。顺便问一下,我建议的范围(l//16+0 if(l:=len(foo))%16==0 else 1):不是您想要的吗?如果不是,你在寻找什么逻辑?这正是我在寻找的!非常感谢你!要么我把它读了一遍,要么它已经不在了。
for i in range( l // 16 + 0 if (l := len(foo))%16 == 0 else 1 ):