简体   繁体   中英

python: using list slice as target of a for loop

I found this code snippet to be very interesting.

a = [0, 1, 2, 3]

for a[-1] in a:
    print(a)

Output is as follows:

[0, 1, 2, 0]
[0, 1, 2, 1]
[0, 1, 2, 2]
[0, 1, 2, 2]

I am trying to understand why python does that. Is it because python is trying to re-use the index? For loop somehow slices the list?

We can add or delete an element while iterating the list, but when we are trying to access the variable using index, it gives bizarre output.

Can someone help me understand the interaction between for loop and index in the list? Or simply explain this output?

It works as expected. (For some interpretation of "expected", at least.)

Re-writing your code to this, to prevent any misinterpretation of what a[-1] is at any point:

a = [a for a in range(0,4)]
for b in a:
    print (b)
    a[-1] = b
    print (a)

shows us

0
[0, 1, 2, 0]
1
[0, 1, 2, 1]
2
[0, 1, 2, 2]
2
[0, 1, 2, 2]

which makes it clear that the b assignment to a[-1] is done immediately, changing the list while iterating.

The four loops do the following:

  1. a[-1] gets set to the first value of the list, 0 . The result is now [0,1,2,0] .
  2. a[-1] gets set to the second value, 1 . The result is (quite obviously) [0,1,2,1] .
  3. a[-1] gets set to 2 and so the result is [0,1,2,2] – again, only a[-1] gets changed.
  4. Finally, a[-1] gets set to the last value in a , so effectively it does not change and the final result is [0,1,2,2] .

a[-1] prints the same value in a[3], the last index in the list. Edit: see comment below for the explanation for this.

The result reads as follows:

[0, 1, 2, 0] -> same as [0, 1, 2, 3], but with a[i] (in this case, a[-1] == a[3]) is replaced with the value at a[0]
[0, 1, 2, 1] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[1]
[0, 1, 2, 2] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[2]
[0, 1, 2, 2] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[3] from the previous iteration.

What happens is

         0 SETUP_LOOP              24 (to 26)
          2 LOAD_GLOBAL              0 (a)
          4 GET_ITER
    >>    6 FOR_ITER                16 (to 24)
          8 LOAD_GLOBAL              0 (a)     //ARRAY (TOS1)
         10 LOAD_CONST               2 (-1)    //DEST (TOS)
         12 STORE_SUBSCR                       //ARRAY[DEST] = TOS2*
        14 LOAD_GLOBAL              1 (print)
         16 LOAD_GLOBAL              0 (a)
         18 CALL_FUNCTION            1
         20 POP_TOP
         22 JUMP_ABSOLUTE            6
    >>   24 POP_BLOCK
    >>   26 LOAD_CONST               0 (None)
         28 RETURN_VALUE

*So if someone could clarify that TOS2 is actually the 'visited' value of the ARRAY?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM