Python 列表内元素转移到另一个,自己写的却不明白为何
题目:将list1内元素移动到list2,最后list1为空。
python"># 我的代码:list1=["c++","java","python","sql","javascript"]
list2=[]
for i in range(len(list1)):
a=list1.pop()
list2.append(a)
print("list1=",list1)
print("list2=",list2)
运行结果: (暂且不管顺序)
list1= []
list2= ['javascript', 'sql', 'python', 'java', 'c++']
我想知道for in过程中发生了什么,于是加了几行print
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)
print("list1=",list1)
print("list2=",list2)
# 结果:0
5
range(0, 5)
__ __ __ __ __ __ __ ___
1
4
range(0, 4)
__ __ __ __ __ __ __ ___
2
3
range(0, 3)
__ __ __ __ __ __ __ ___
3
2
range(0, 2)
__ __ __ __ __ __ __ ___
4
1
range(0, 1)
__ __ __ __ __ __ __ ___
list1= []
list2= ['javascript', 'sql', 'python', 'java', 'c++']
i / len(list1) / range(len(list1))同时变化:
遍历 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
i | 0 | 1 | 2 | 3 | 4 |
len(list1) | 5 | 4 | 3 | 2 | 1 |
range(len(list1)) | range(0, 5) | range(0, 4) | range(0, 3) | range(0, 2) | range(0, 1) |
i 是从range(len(list1))中逐次取值的,那么应该在第4次就取不到值然后截止了—— i=3 & range(len(list1))=range(0, 2) 是矛盾的啊~
回答:
for i in 表达式x
这里的表达式只在循环开始时演算一次
相当于
y=表达式xfor 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]),如果这个变量本身发生了变化,自然会影响到循环的.
回答:
我的问题栏太乱了,所以我把一些东西写在这,希望帮助我的朋友看这里。
求助了几个论坛,目前只有咱这个站有热心前辈帮忙,但也许是我提问水平有限,我还是一头雾水,于是在朋友提醒下去stackoverflow看了看,由于英文很差,用google翻译磕磕绊绊的发了贴。
也许是时差,答复的很快,有个人特意解释了一篇。
原文:
The for instruction is creating an iterator from the object specified after in. This iterator is returning the next() of this iterator at each iteration. When you pop item out of list (first method) next() as no more value after 3 iterations and stops. When you use the range the range object and its iterator are created first and remain unchanged by the list pop.google翻译:
for指令从in之后指定的对象创建一个迭代器。此迭代器在每次迭代时都返回该迭代器的next()。 当您从列表中弹出项目(第一种方法)时,next()作为3次迭代并停止后没有更多值。 使用范围时,将首先创建范围对象及其迭代器,并在列表弹出窗口中保持不变。
由于我的英文太烂,只读出一个信息:len()函数就是本质与list1不同的! list1在for in 循环中每次都会变动,所以遍历起来会不完整; 而len()函数就是有一个特征——在for in循环中第一次执行就定型,不论在循环中如何更改,i 只会在循环初始的len()函数中遍历.
我不知道译文是否正确,我理解是否到位,但好像也只能这样了。
谢谢 Yujiaao 的帮助,感谢。
唉~ 还是感叹,自学真的很多坑。
以上是 Python 列表内元素转移到另一个,自己写的却不明白为何 的全部内容, 来源链接: utcz.com/a/160510.html