我有这个代码:
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/