Python UnboundLocalError:在理解中赋值之前引用的局部变量
我正在玩Python UnboundLocalError:在理解中赋值之前引用的局部变量,python,python-3.8,dictionary-comprehension,Python,Python 3.8,Dictionary Comprehension,我正在玩dict理解,并尝试(:=操作符),示例如下: columns={'idx','class_name'} #以某种方式填充它们 # ... retval={names[idx]:idx代表范围内的idx(len(names)),如果(names:=list(columns))} 因此,基本上是一个dict,它包含集合中的项和一个迭代该项的值。 但是,names似乎是一个UnboundLocalError 下面是我试图做的,捕获理解范围外变量的别名: names = list(colum
dict
理解,并尝试(:=
操作符),示例如下:
columns={'idx','class_name'}
#以某种方式填充它们
# ...
retval={names[idx]:idx代表范围内的idx(len(names)),如果(names:=list(columns))}
因此,基本上是一个dict
,它包含集合
中的项和一个迭代该项的值。
但是,names
似乎是一个UnboundLocalError
下面是我试图做的,捕获理解范围外变量的别名:
names = list(columns)
retval = {names[idx]:idx for idx in range(len(names))}
为什么这是一个错误
编辑
在捕获的列中尝试此操作:
retval = {names[idx]:idx for idx in range(len(names:= list(columns)))}
产生了一个更有意义的IMHO错误:
SyntaxError: assignment expression cannot be used in a comprehension iterable expression
因此,正如下面的回答,这不是使用海象操作符的方式。您误用了条件。对于从迭代器中检索到的每个值,它将被评估一次;它不能用于定义迭代器<当您尝试计算len(names)
时,尚未定义code>names
当您可以使用enumerate
时,使用range
有点反模式;试一试
retval = {name: idx for idx, name in enumerate(columns)}
请注意,
列
无论如何都没有可靠的顺序;集合不保留项的添加顺序,如dict
s do.。。。显然,如果
部分是在部分的之后计算的(否则有什么可以过滤的?),对吗?在第一个代码中,您从未定义名为name的变量,因此执行range(len(names))将失败,因为没有可调用的名称。请澄清您认为第一个代码应该做什么?您可以通过更简单的理解产生相同的结果retval1={val:index for index,val in enumerate(columns)}
只是一个旁注,我认为如果:=
是在名称
(在范围(len(names))
部分)的第一次使用中完成的,它会起作用。因此操作符:=
没有在理解的范围内定义新的局部变量,它更像是一个别名?它是,但是语义不同于赋值语句,因为它是一个普通表达式。(即使它像赋值语句,它仍然是未定义的,即使它被标记为将是局部的。)假设理解中的迭代变量是理解范围之外唯一可见的变量,因此,我尽可能地理解了这项任务。我猜我错了,赋值只在理解的范围内被接受。迭代变量可能是可见的,但这只是它是否是自由变量的问题。例如,[z代表y,x代表z,y代表z]
:x
是一个自由变量,因此要么有一个超出理解范围的值,要么引发一个namererror
<代码>y
被迭代,但它是列表的局部<代码>:=只要在计算表达式时在作用域中创建一个新名称即可。(事实上,=
也是如此,除了仅仅存在一个=
就足以隐藏一个全局变量,不管是否定义了本地名称。)