【问题标题】:Converting iterator to list changes the iterator将迭代器转换为列表会更改迭代器
【发布时间】:2016-03-18 21:45:57
【问题描述】:

下面的代码产生了一些非常奇怪的结果

import re
string = "test test test"
positions = re.finditer("test", string)
print (list(positions))
print (list(positions))

输出:

[<Match object...>, <Match object...>, <Match object...>]
[]

现在,我想我知道这里发生了什么。第一个 list 调用“耗尽”迭代器(所以它“使用迭代器”,就像在生成器中一样,在从迭代器创建列表的过程中)所以当第二次调用 list 时,迭代器消失了,我们得到一个空列表。下面的段落似乎证实了这一点,尽管我试图理解他们在这里所说的一些事情,所以我对这个解释并不完全满意(如果它是正确的):

一个容器对象(比如一个列表)产生一个新的迭代器 每次将它传递给 iter() 函数或在 for 循环中使用它。 用迭代器尝试这个只会返回同样的疲惫 在上一次迭代过程中使用的迭代器对象,使其出现 像一个空容器。

以上段落来自the official documentation

我不太明白他们在上一段第一句话中所说的内容,尤其是关于传递给iter() 函数的内容,而且我不知道他们如何将 for 循环中的用法与生成的列表联系起来一个全新的迭代器。不过,第二句话似乎更接近我最初认为的上面代码中的内容。

如果有人能帮我解决这里的困惑,我将不胜感激。

注意:

我正在使用 Python 3.5.1

【问题讨论】:

    标签: python list iterator


    【解决方案1】:

    这一行:

    positions = re.finditer("test", string)
    

    It returns a one-shot iterator。然后你在同一个迭代器上调用了list(positions)两次

    所以对于第二次通话,它已经筋疲力尽了。

    每次迭代列表时,列表都会为您提供一个新的迭代器,因此列表本身不会有令人筋疲力尽的行为。比较以下行为以了解您引用的文档:

    >>> L = ['a', 'b', 'c']
    >>> list(L)
    ['a', 'b', 'c']
    >>> list(L)
    ['a', 'b', 'c']
    >>> iter_L = iter(L)  # calls L.__iter__() and returns you a one-shot iterator
    >>> list(iter_L)
    ['a', 'b', 'c']
    >>> list(iter_L)
    []
    

    【讨论】:

    • 一次性迭代器?
    • 是的。你只能迭代一次。
    • 好的,但这就是我所说的我已经想到的(它第一次耗尽了迭代器,然后第二次它就消失了)。但没关系,我想我已经弄清楚我在问题中引用的段落在说什么。
    • 哈哈,正准备用您对答案所做的最新编辑来回答我自己的问题(代码以L = ['a'... 开头)。但我看到你打败了我
    • 请注意,您在原问题中看到的行为与list.__iter__无关,与re.finditer的合同有关。
    【解决方案2】:

    当 list() 在迭代器上运行时,它基本上会在其上调用 next() 直到引发异常 StopIteration,然后将 next() 返回的每个内容附加到列表中,然后返回该列表。基本上,list(iter) 的实现可能是:

    my_list(iter):
        output = []
        try:
            while True:
                output.append(iter.next())
        except StopIteration:
            return output
    

    顺便说一句,for 循环做同样的事情,但它不是output.append(iter.next()) 而是循环的主体。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 2020-05-18
      • 2011-03-24
      • 2016-12-14
      • 2011-09-02
      • 2012-10-11
      • 1970-01-01
      相关资源
      最近更新 更多