python:使用列表切片作为for循环的目标

Posted

技术标签:

【中文标题】python:使用列表切片作为for循环的目标【英文标题】:python: using list slice as target of a for loop 【发布时间】:2018-12-29 20:22:52 【问题描述】:

我发现这段代码 sn-p 很有趣。

a = [0, 1, 2, 3]

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

输出如下:

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

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

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

有人可以帮我理解 for 循环和列表中索引之间的交互吗?还是简单解释一下这个输出?

【问题讨论】:

有趣的问题。不过,我会尝试找到一个更好的标题。它很笼统,你真的会认为它是一个“问题”吗? 想象for x in a: a[-1] = x 一开始我以为代码不行,后来我以为最后输出的后面应该有一个三。软化。感谢您的提问。 只有a[-1] 才使这变得有点有趣。等效的for a[0] in a 清楚地表明没有切片,没有意外的交互,也没有奇怪的输出。更清楚的是,只有一个元素会发生变化。 【参考方案1】:

它按预期工作。 (至少对于“预期”的一些解释。)

为此重写您的代码,以防止任何时候对 a[-1] 的任何误解:

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

向我们展示

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

这清楚地表明b 分配a[-1] 立即完成,在迭代时更改列表。

四个循环执行以下操作:

    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]

【讨论】:

【参考方案2】:

a[-1] 在列表中的最后一个索引 a[3] 中打印相同的值。编辑:请参阅下面的评论以获取对此的解释。

结果如下:

[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.

【讨论】:

“它可能在负方向上有一个超出范围的索引”:不,这是perfectly ordinary Python syntax。它在#3 下的the official documentation 中提到。【参考方案3】:

会发生什么

         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 实际上是 ARRAY 的“已访问”值?

【讨论】:

以上是关于python:使用列表切片作为for循环的目标的主要内容,如果未能解决你的问题,请参考以下文章

python中的for i in range怎么用

简单python for循环上的列表索引超出范围错误

Python列表操作:遍历、range()、列表解析、列表切片、列表复制、元组

列表切片的for循环

python基础学习-列表

从for循环Python打印数字列表作为数组