【问题标题】:for loop using enumerate terminates unexpectedly使用枚举的 for 循环意外终止
【发布时间】:2019-10-09 18:48:22
【问题描述】:

这是一个通过枚举对象的简单 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() 是一个迭代器。它只能循环一次。 list() 循环遍历迭代器。

标签: python for-loop enumerate


【解决方案1】:

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

【讨论】:

  • 太棒了。谢谢。你回答得很好,很快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 2012-01-30
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多