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
循环可以遍历不断变化的可迭代对象外,这毫无意义。它之所以有效,是因为生成器中的 lst
与 nums
是同一个对象,因此它的长度在每次迭代中都是 re-evaluated。
如果有必要使用 for 而不是 while,那么这里有一些想法:
如果目的是避免运行 由于列表在运行时收缩而超出列表边界(我没有测试过),那么我会在正文的关键部分放置一个条件根据 len(n) 重新评估 i 并相应地中断。
如果目的是在长度扩展的情况下继续使用 for 循环,那么也许我会考虑嵌套循环,外部存在 while True 并具有中断条件(如果我达到 len(n))。在那种情况下,内循环的起始值不会总是零。
在 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
循环可以遍历不断变化的可迭代对象外,这毫无意义。它之所以有效,是因为生成器中的 lst
与 nums
是同一个对象,因此它的长度在每次迭代中都是 re-evaluated。
如果有必要使用 for 而不是 while,那么这里有一些想法:
如果目的是避免运行 由于列表在运行时收缩而超出列表边界(我没有测试过),那么我会在正文的关键部分放置一个条件根据 len(n) 重新评估 i 并相应地中断。
如果目的是在长度扩展的情况下继续使用 for 循环,那么也许我会考虑嵌套循环,外部存在 while True 并具有中断条件(如果我达到 len(n))。在那种情况下,内循环的起始值不会总是零。