range(len()) 可以在 for 循环中多次计算吗?

Can range(len()) be evaluated multiple times within a for loop?

在 while 循环中,条件 get 被迭代地重新评估。示例:

while i < len(nums):

最新索引i和最新长度nums都被用来重新判断条件

在 for 循环中不是这种情况。示例:

for i in range(len(nums)):

此处创建了 range(len(nums)),并且即使 nums 的长度发生变化(例如,由于循环中的弹出值)也保持不变。我对这个过程的理解是否正确?有没有办法让 for 循环依赖于 'a moving goal post'(变化的 nums 长度)?

This is not the case within a for-loop

没有。创建 range 对象时就是这种情况。 range 不存储对 nums 的引用,它只取整数。如果你有一个列表

ls = [0, 1, 2, 3]

那么你可以这样写:

for i in ls:
    ls.append(i)

并且循环将永远 运行,因为您从 ls 获得 i 并且每次都添加 ls。不过,我不建议尝试使用它来实现您的目标。在这里使用 while 循环很有意义。

你可以使用变量并为每个循环设置数组的长度

 nums = [1, 2 ,3 ,4]
 i=0
 array_length=len(nums)
 while i < array_length:
   nums.pop()
   print(nums)
   array_length=len(nums)

您可以使用 enumerate(nums) 遍历列表以获取当前索引,如果列表变长,您仍然可以继续。

在下面的示例中,我使用了 random 来有机会在每次迭代中应用一个新项目。

>>> import random
>>>
>>> nums = ["a", "a"]
>>>
>>> for i, val in enumerate(nums):
...    if random.randint(0, 1)==0:
...       nums.append("b")
...    print(str(i)+":"+val)
...
0:a
1:a
2:b
3:b

您可以制作一个简单地隐藏 while 循环的生成器。

def range_len(lst):
    i = 0
    while i < len(lst):
        yield i
        i += 1

for i in range_len(nums):
    ...

除了证明 for 循环可以遍历不断变化的可迭代对象外,这毫无意义。它之所以有效,是因为生成器中的 lstnums 是同一个对象,因此它的长度在每次迭代中都是 re-evaluated。

如果有必要使用 for 而不是 while,那么这里有一些想法:

如果目的是避免运行 由于列表在运行时收缩而超出列表边界(我没有测试过),那么我会在正文的关键部分放置一个条件根据 len(n) 重新评估 i 并相应地中断。

如果目的是在长度扩展的情况下继续使用 for 循环,那么也许我会考虑嵌套循环,外部存在 while True 并具有中断条件(如果我达到 len(n))。在那种情况下,内循环的起始值不会总是零。