Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
413 views
in Technique[技术] by (71.8m points)

Python 列表内元素转移到另一个,自己写的却不明白为何

题目:将list1内元素移动到list2,最后list1为空。

# 我的代码:
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("__ __ __ __ __ __ __ __
")
    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) 是矛盾的啊~


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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("__ __ __ __ __ __ __ __
")
    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 ('__ __ __ __ __ __ __ __
')
             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]),如果这个变量本身发生了变化,自然会影响到循环的.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...