使用枚举的 for 循环意外终止

for loop using enumerate terminates unexpectedly

这是一个遍历枚举对象的简单 for 循环。由于(我在评论中提到的这一行)而终止。这是为什么?

enum_arr = enumerate(arr)
for ele in enum_arr:
    print(ele)
    print(list(enum_arr)[ele[0]:]) # terminates due to this line

输出:

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

如果我注释掉第二个打印语句,那么:

输出:

(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
(5, 5) 

不出所料。 为什么会这样?

enumerate() 给你一个 iterator object。迭代器就像书中的书签,只能向前移动;一旦读到书的末尾就不能再返回了,必须创建一个新书签。

然后您在两个地方使用该迭代器; for 循环和 list()list() 函数将书签一直移动到末尾,因此 for 循环无法再将其移动。

如果你想使用一个单独的、独立的迭代器,你必须在循环中创建一个 new enumerate() 对象:

enum_arr = enumerate(arr)
for ele in enum_arr:
    print(ele)
    print(list(enumerate(arr[ele[0]:], ele[0])))

这确实需要 arr 本身 而不是 迭代器,它必须是一个序列,以便您可以对其进行索引。我在这里假设您有一个列表、元组、范围或类似的值。

请注意,我传入了两次 ele[0]enumerate() 的第二个参数允许您设置计数器的起始值。

这里使用元组赋值来分离计数和值更容易:

for count, value in enum_arr:
    print((count, value))
    print(list(enumerate(arr[count:], count)))

演示:

>>> arr = range(6)
>>> enum_arr = enumerate(arr)
>>> for count, value in enum_arr:
...     print((count, value))
...     print(list(enumerate(arr[count:], count)))
...
(0, 0)
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
(1, 1)
[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
(2, 2)
[(2, 2), (3, 3), (4, 4), (5, 5)]
(3, 3)
[(3, 3), (4, 4), (5, 5)]
(4, 4)
[(4, 4), (5, 5)]
(5, 5)
[(5, 5)]

回到书的类比,要求arr是一个序列:只要arr是有页码的书,您可以随时添加更多书签。如果它是其他一些 iterable type,那么您无法对其进行索引,因此必须找到一些其他方法来 'skip ahead' 并再次返回。进一步延伸类比:假设这本书正在 流式传输 给你,一次一页,那么一旦你收到所有页面就不能返回。解决方案可能是首先创建页面的本地缓存;如果你可以节省 cached_copy = list(arr) 可以完成的内存。请注意,您必须确保您收到的书的长度不会超过您实际拥有的 space。有些迭代器是无限的,所以需要无限的内存!