首页 > 解决方案 > 使用枚举的 for 循环意外终止

问题描述

这是一个通过枚举对象的简单 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) 

正如预期的那样。为什么会这样?

标签: pythonfor-loopenumerate

解决方案


enumerate()给你一个迭代器对象。迭代器就像一本书中的书签,只能向前移动;一旦你到达书的结尾,你就不能再回去了,必须做一个新的书签。

然后在两个地方使用该迭代器;循环forlist(). 该list()函数将书签一直移动到末尾,因此for循环不能再移动它。

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

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

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

请注意,我传入了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是有页码的书,你可以在任何时候添加更多的书签。如果它是其他一些可迭代类型,那么你不能索引到它,因此必须找到一些其他方法来“向前跳过”并再次返回。进一步扩展类比:假设正在向您流式传输这本书,一次一页,那么一旦您收到所有页面,您就无法返回。解决方案可以是首先创建页面的本地缓存;如果您可以节省可以使用的内存cached_copy = list(arr). 只需考虑到您必须确保您收到的书不会太长以至于需要比实际空间更多的空间。有些迭代是无穷无尽的,所以需要无限的内存!


推荐阅读