Python оператор моржа терпит неудачу в пределах диапазона - PullRequest
2 голосов
/ 09 апреля 2020

Почему я могу использовать что-то вроде

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

1 Ответ

2 голосов
/ 09 апреля 2020

В списке аргументов выражения оцениваются слева направо, поэтому в:

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

первый аргумент range( len( (Y := foo) )) оценивается перед вторым аргументом Y, и поэтому Y определяется с помощью foo перед тем, как Y упоминается как второй аргумент.

Однако в условном выражении выражение в выражении if вычисляется до того, как будет выполнено вычисление любого из выходных выражений, поэтому в :

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

l%16 == 0 вычисляется первым, и, поскольку l еще не определено в этой точке, оно вызывает указанное NameError.

Вместо этого можно определить l в предложении if сначала, если это действительно логин c, который вы хотите:

for i in range( l // 16 + 0 if (l := len(foo))%16 == 0 else 1 ):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...