for循环使用枚举意外终止

问题描述 投票:0回答:1

这里是一个简单的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) 

如预期。为什么会这样?

python for-loop enumerate
1个回答
0
投票

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,则您无法对其进行索引,因此必须找到其他手段来“向前跳过”并再次返回。进一步推论:说这本书一次被[[streamed传送给您,一次一页,那么一旦您收到所有的页面,就无法返回。解决方案是首先创建页面的本地缓存;如果您可以节省可以用cached_copy = list(arr)完成的内存。只需考虑到您必须确保所收到的书不需要占用比实际更多的空间即可。而且某些可迭代对象是无穷无尽的,因此需要无限的内存!

© www.soinside.com 2019 - 2024. All rights reserved.