python:使用list slice作为for循环的目标

python: using list slice as target of a for loop

我发现这个代码片段非常有趣。

1
2
3
4
a = [0, 1, 2, 3]

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

输出如下:

1
2
3
4
[0, 1, 2, 0]
[0, 1, 2, 1]
[0, 1, 2, 2]
[0, 1, 2, 2]

我试图理解为什么Python会这样做。是因为python试图重用索引吗?for循环以某种方式分割列表?

我们可以在迭代列表时添加或删除一个元素,但是当我们尝试使用索引访问变量时,它会给出奇怪的输出。

有人能帮助我理解for循环和列表中索引之间的交互吗?或者简单地解释一下这个输出?


它按预期工作。(至少对于"预期"的某些解释。)

重新编写您的代码,以防止在任何时候对a[-1]的内容有任何误解:

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

展示给我们看

1
2
3
4
5
6
7
8
0
[0, 1, 2, 0]
1
[0, 1, 2, 1]
2
[0, 1, 2, 2]
2
[0, 1, 2, 2]

这就清楚地表明,对a[-1]b赋值是立即完成的,在迭代时更改列表。

四个循环执行以下操作:

  • a[-1]被设置为列表的第一个值,0。结果是现在的[0,1,2,0]
  • a[-1]设置为第二个值,1。结果(很明显)是[0,1,2,1]
  • a[-1]被设置为2,因此结果是[0,1,2,2]——同样,只有a[-1]被更改。
  • 最后,a[-1]被设置为a中的最后一个值,因此有效地不会改变,最终结果是[0,1,2,2]

  • a[-1]在列表中的最后一个索引[3]中打印相同的值。编辑:请参阅下面的注释了解有关此问题的解释。

    结果如下:

    1
    2
    3
    4
    [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.


    所发生的是

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
             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

    *那么,如果有人能澄清TOS2实际上是数组的"访问"值?