【问题标题】:Python iterator is empty after performing some action on itPython迭代器在对其执行某些操作后为空
【发布时间】:2017-11-19 18:37:15
【问题描述】:

我试图在 python3 中对 codeeval 进行挑战,但在尝试改进我的解决方案时遇到了困难。每次我尝试在同一个迭代器上连续两次迭代(或打印或其他操作)时,第二个循环都是空的。这是一个产生这种行为的最小示例,尽管我尝试了几种与列表等不同的组合,但结果相同:

numbers = ('1','2','3','4','5')
numbers = map(int, numbers)                                                    
print(list(numbers))                                                          
print(list(numbers))

结果:

[1, 2, 3, 4, 5]
[]

为什么 print(在这种情况下)会删除数字的内容?

【问题讨论】:

  • 这就是迭代器的本质。一旦完成,它保持完成。

标签: python python-3.x


【解决方案1】:

这正是迭代器的工作方式。它们的设计目的是只生成一次动态数据,不再重复。如果您想再次从中获取数据,则必须将所有迭代数据保存到另一个列表中,或者再次启动迭代器。如果您需要从文件中读取数据或执行其他烦人的操作以重新获取该迭代器,最好在生成该数据时将该数据存储在一个列表中。

>>> numbers = ('1','2','3','4','5')
>>> ints = [x for x in map(int, numbers)]
>>> print(list(ints))
[1, 2, 3, 4, 5]
>>> print(list(ints))
[1, 2, 3, 4, 5]

https://docs.python.org/2/library/stdtypes.html#iterator-types

协议的意图是一旦迭代器的 next() 方法 引发 StopIteration,它将在后续调用中继续这样做。 不遵守此属性的实现被视为已损坏。 (此约束是在 Python 2.3 中添加的;在 Python 2.2 中,各种 迭代器根据此规则被破坏。)

我应该注意,我在 Python 2.4.3 上运行了您提供的确切代码,并且每次都打印出列表。所以这是一个版本依赖的事情,我想。

【讨论】:

  • 您可以再次调用map 函数。虽然如果你要这样做,最好不要这样做numbers = map(int, numbers)。尝试给它另一个名称,例如ints = map(int, numbers)。这样您就不会破坏原始数据。
  • 重新启动迭代器的方法是什么?我真的必须为每次打印映射它吗?此外,在我的具体演员表(但不是最小的例子)中,初始列表来自 open('file') 语句。我也必须这样做两次吗?
  • @Guerki 你可能不得不这样做,是的。在这种情况下,您应该遍历数据并将其保存到列表中;这将把数据永久保存在那里。我会更新我的答案。
  • @TheSoundDefense:在 Python 3.x 中,许多以前返回列表的函数现在返回迭代器。在这种情况下,map() 已以这种方式转换。所以等效的py3k代码是:ints = list(map(int, numbers))
  • 另一件值得注意的事是itertools.tee(),如果您不认为要遍历整个迭代器,这可能会有所帮助,但您可能需要多次迭代到该点次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多