python - 缩短运行中循环的长度

标签 python python-2.7 loops

我有这个代码:

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

for i in range(0,len(numbers),1):
    print 'i = {} , len(numbers) = {}'.format(i,len(numbers))
    numbers.remove(i)

输出是:

i = 0 , len(numbers) = 5
i = 1 , len(numbers) = 4
i = 2 , len(numbers) = 3
i = 3 , len(numbers) = 2
i = 4 , len(numbers) = 1

我的问题是,为什么一旦“i”大于“len(numbers)”,循环就不会停止运行? (第 4 行)

谢谢

最佳答案

列表的长度与此无关。要了解原因,请继续阅读。

首先,您误解了 range 函数的作用。来自文档:

range(start, stop[, step]) This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops.

range 的作用是创建一个(某种程度上)数字列表 (python2),并对其进行迭代。

>>> range(0, 5, 1)
[0, 1, 2, 3, 4]

这可能看起来相同,但实际上是一个完全不同的列表。您可以通过将返回值分配给变量,然后打印出该变量的 id()numbers 来确认这一点。

您想要做的是迭代实际列表,而不是由range函数生成的列表。您可以通过稍微更改循环定义来做到这一点:

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

ctr = 0
for i in numbers:
    print('i = {} , len(numbers) = {}'.format(ctr, len(numbers)))
    numbers.remove(i)
    ctr += 1

输出:

i = 0 , len(numbers) = 5
i = 1 , len(numbers) = 4
i = 2 , len(numbers) = 3

现在,您会看到,每次迭代之后,列表都会变短,直到在 i 达到 4 之前列表耗尽。

要理解为什么,它会这样发生:

Iteration 0
    0   1   2   3   4    (numbers)
   ctr

Iteration 1 (0 deleted)
    1   2   3   4        (numbers)
      ctr

Iteration 2 (1 deleted)
    2   3   4            (numbers)
           ctr

End (2 deleted)

这里,ctr就像一个指针,指向列表中的当前元素。循环的每次迭代,ctr 都会前进一步到下一个元素。

现在,每次删除一个元素时,不仅列表大小会缩小,而且迭代器会前进一步,因此您实际上前进了两次

我们如何防止这种情况发生?您已经找到了解决方案。使用范围

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

ctr = 0
for i in range(0, len(numbers), 1):
    print('i = {} , len(numbers) = {}'.format(ctr, len(numbers)))
    numbers.remove(i)
    ctr += 1

这就是发生的事情:

Iteration 0 
    0   1   2   3   4   (numbers)
    0   1   2   3   4   (range)
    ctr


Iteration 1 (0 deleted)
    1   2   3   4       (numbers)
    0   1   2   3   4   (range)
        ctr

Iteration 2 (1 deleted)
    2   3   4           (numbers)
    0   1   2   3   4   (range)
           ctr

Iteration 3 (2 deleted)
    3   4               (numbers)
    0   1   2   3   4   (range)
               ctr

Iteration 4 (3 deleted)
    4                   (numbers)
    0   1   2   3   4   (range)
                   ctr

End (4 deleted) 

所以,你得到:

i = 0 , len(numbers) = 5
i = 1 , len(numbers) = 4
i = 2 , len(numbers) = 3
i = 3 , len(numbers) = 2
i = 4 , len(numbers) = 1

TL;DR

总而言之,当您迭代副本时,原始列表将缩小,这意味着长度也会减少,但由于您正在迭代 range 对象,该对象返回从 0 到 0 的数字序列4(含)并且不受后续删除的影响,循环将运行 5 次迭代(等于 range 返回的元素数量)。

关于python - 缩短运行中循环的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44750509/

相关文章:

python - 如何在 Python 中检查下一个 iter 项而不继续进行 For 循环

loops - Cypress.io 迭代元素列表以查看文本是否不存在,然后执行操作以添加元素

python - (OSError) 异常处理 (ConnectionRefusedError) 错误

python - 将列表映射到 1 和 0

将输入作为字符串值进行插入排序的 Python 代码

vb.net - 嵌套 For 循环 vb.net

java - 重复循环大量对象时如何优化性能

python - NumPy 数组中每个字符串的长度

python - plt.cm.get_cmap 中可以使用哪些名称?

python-2.7 - 如何在 Ros-python 脚本中导入 Webots Controller