Python 为什么在for循环中允许使用列表订阅?
Python如何接受以下构造:Python 为什么在for循环中允许使用列表订阅?,python,for-loop,syntax,Python,For Loop,Syntax,Python如何接受以下构造: l = [1, 2, 3, 4] for i, l[i] in enumerate(l[:]): print(l[i]) 似乎没有抱怨,它愉快地打印出1234。这是如何允许的以及它的具体作用是什么?允许迭代变量为目标列表中指定的任何变量: for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite] 其中,对于以下构造: t
l = [1, 2, 3, 4]
for i, l[i] in enumerate(l[:]):
print(l[i])
似乎没有抱怨,它愉快地打印出1234
。这是如何允许的以及它的具体作用是什么?允许迭代变量为目标列表中指定的任何变量:
for_stmt ::= "for" target_list "in" expression_list ":" suite
["else" ":" suite]
其中,对于以下构造:
target_list ::= target ("," target)* [","]
target ::= identifier
| "(" [target_list] ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target
这意味着您还可以执行其他古怪的操作,如分配给切片:
for l[::-1] in [l, l, l]: pass
或订阅:
class Foo: a = 20
for Foo.a in range(2): pass
但我真的不知道你为什么要这么做
这是循环
s的副产品,基本上为每次迭代执行赋值语句,如参考文献中所述:
使用标准分配规则(请参见分配语句)将每个项目依次分配到目标列表,然后执行套件
因此,循环所做的是,它从表达式列表
中获取迭代器,并对目标列表
中的每个值执行赋值。本质上等同于以下while
循环:
it = enumerate(l[:])
while True:
try:
i, l[i] = next(it)
print(l[i])
except StopIteration:
break
dis
还可以在字节码级别显示此行为。使用稍微简化的版本:
def _():
for i, l[i] in enumerate(l[:]):
pass
您将获得以下输出:
dis(_)
2 0 SETUP_LOOP 40 (to 43)
3 LOAD_GLOBAL 0 (enumerate)
6 LOAD_GLOBAL 1 (l)
9 LOAD_CONST 0 (None)
12 LOAD_CONST 0 (None)
15 BUILD_SLICE 2
18 BINARY_SUBSCR
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 GET_ITER
>> 23 FOR_ITER 16 (to 42)
26 UNPACK_SEQUENCE 2
29 STORE_FAST 0 (i)
32 LOAD_GLOBAL 1 (l)
35 LOAD_FAST 0 (i)
38 STORE_SUBSCR
3 39 JUMP_ABSOLUTE 23
>> 42 POP_BLOCK
>> 43 LOAD_CONST 0 (None)
46 RETURN_VALUE
如果相关赋值是在命令的FOR\u ITER
之后执行的:
26 UNPACK_SEQUENCE 2
29 STORE_FAST 0 (i)
32 LOAD_GLOBAL 1 (l)
35 LOAD_FAST 0 (i)
38 STORE_SUBSCR
解压缩序列并将其分配给i
和l[i]
如果你也反汇编
dis('i,l[i]=(1,2)
,你会发现如果你忽略元组(1,2)
的初始加载和值的返回,操作是完全相同的。@johnsharpe你到底是怎么找到它的?我找了整整20分钟,但什么也找不到!:-)我在谷歌上搜索了“for loop目标列表中的python订阅”,这是第六次点击。我当然错过了。啊,好吧,又是一个路标!这里的问题不就是解释赋值的顺序以及绑定创建的顺序吗?这使得while示例本身不具有解释性?@pvg否否我试图强调的问题是,有一个赋值正在进行,因此target\u列表中的任何内容都可以作为for循环的迭代变量。编写while
是为了显示执行的命令序列的友好形式,以及它如何包含隐藏的赋值。啊,你说得对,我明白你的意思。很明显,我患有python绑定和作用域斯德哥尔摩综合症。@pvg-hah,那么您可以检查一下,这很好地解释了for循环
s:-)中的作用域情况