for i in 表达式x 这里的表达式只在循环开始时演算一次
相当于
y=表达式x
for i in y:
...
把
list1=["c++","java","python","sql","javascript"]
list2=[]
for i in range(len(list1)):
print(i)
print(len(list1))
print(range(len(list1)))
print("__ __ __ __ __ __ __ __\n")
a=list1.pop()
list2.append(a)
pass
print("list1=",list1)
print("list2=",list2)
存成 test.py
执行 python -m dis test.py
会得到字节码如下:
1 0 LOAD_CONST 0 ('c++')
3 LOAD_CONST 1 ('java')
6 LOAD_CONST 2 ('python')
9 LOAD_CONST 3 ('sql')
12 LOAD_CONST 4 ('javascript')
15 BUILD_LIST 5
18 STORE_NAME 0 (list1)
2 21 BUILD_LIST 0
24 STORE_NAME 1 (list2)
3 27 SETUP_LOOP 89 (to 119)
30 LOAD_NAME 2 (range)
33 LOAD_NAME 3 (len)
36 LOAD_NAME 0 (list1)
39 CALL_FUNCTION 1
42 CALL_FUNCTION 1
45 GET_ITER
>> 46 FOR_ITER 69 (to 118)
49 STORE_NAME 4 (i)
4 52 LOAD_NAME 4 (i)
55 PRINT_ITEM
56 PRINT_NEWLINE
5 57 LOAD_NAME 3 (len)
60 LOAD_NAME 0 (list1)
63 CALL_FUNCTION 1
66 PRINT_ITEM
67 PRINT_NEWLINE
6 68 LOAD_NAME 2 (range)
71 LOAD_NAME 3 (len)
74 LOAD_NAME 0 (list1)
77 CALL_FUNCTION 1
80 CALL_FUNCTION 1
83 PRINT_ITEM
84 PRINT_NEWLINE
7 85 LOAD_CONST 5 ('__ __ __ __ __ __ __ __\n')
88 PRINT_ITEM
89 PRINT_NEWLINE
8 90 LOAD_NAME 0 (list1)
93 LOAD_ATTR 5 (pop)
96 CALL_FUNCTION 0
99 STORE_NAME 6 (a)
9 102 LOAD_NAME 1 (list2)
105 LOAD_ATTR 7 (append)
108 LOAD_NAME 6 (a)
111 CALL_FUNCTION 1
114 POP_TOP
10 115 JUMP_ABSOLUTE 46
>> 118 POP_BLOCK
12 >> 119 LOAD_CONST 6 ('list1=')
122 LOAD_NAME 0 (list1)
125 BUILD_TUPLE 2
128 PRINT_ITEM
129 PRINT_NEWLINE
13 130 LOAD_CONST 7 ('list2=')
133 LOAD_NAME 1 (list2)
136 BUILD_TUPLE 2
139 PRINT_ITEM
140 PRINT_NEWLINE
141 LOAD_CONST 8 (None)
144 RETURN_VALUE
这里简化一下, for 循环编译后,分成二阶段执行,一个是SETUP_LOOP,一个是FOR_ITER:
3 27 SETUP_LOOP 89 (to 119)
... #初始化阶段
45 GET_ITER #得到迭代变量
>> 46 FOR_ITER 69 (to 118)
... #循环体
10 115 JUMP_ABSOLUTE 46
循环第二阶段是在46 FOR_ITER ~ JUMP_ABSOLUTE 46这两条之间进行,不会再对初始化代码的运行,但循环本身是围绕迭代变量进行的(上面的 range的结果[0,1,2,3,4]),如果这个变量本身发生了变化,自然会影响到循环的.