关于Python中的生成器和迭代器的3个问题

时间:2018-06-09 19:46:41

标签: python generator

如果您将结果放入列表中,则每个人都说您失去了生成器的好处。

  1. 但是你需要一个列表或序列,甚至可以开始使用生成器,对吧?因此,例如,如果我需要浏览目录中的文件,我是否必须先将它们放入列表中,就像使用os.listdir()一样?如果是这样,那么效率如何呢? (我总是使用字符串和文件,所以我真的很讨厌所有的例子都使用范围和整数,但我离题了)

  2. 更进一步,仅仅存在yield关键字应该是一个生成器。所以,如果我这样做:

    for x in os.listdir():
        yield x
    
  3. 是否仍在创建列表?或者os.listdir()本身现在也神奇地是一个发电机?是否有可能,os.listdir()还没有被调用,那里还没有列表呢?

    1. 最后,我们被告知迭代器需要 iter ()和 next ()方法。但这不也意味着他们需要一个指数吗?如果没有,next()操作是什么?如何在没有索引的情况下知道下一步是什么?在3.6之前,dict键没有顺序,那么迭代是如何工作的呢?

2 个答案:

答案 0 :(得分:1)

  1. 没有
  2. 看,这里没有列表:

    def one():
        while True:
            yield 1
    
    1. 索引和next()是执行迭代的两个独立工具。同样,如果你有一个对象,它的迭代器next()总是返回1,你就不需要任何索引。
    2. 更深入的细节......

      从技术上讲,你可以随时将列表和索引与任何生成器或迭代器相关联:简单地写下它所有返回的值 - 你将得到最多可数的值集合a 0,a 1,...但是那些是仅仅是一种数学形式主义,与一个真正的发电机如何工作有着不必要的共同点。例如,你有一个总是产生一个的发电机。你可以计算到目前为止你从中获得了多少,并称之为索引。您可以记下所有那些,以逗号分隔,并将其称为列表。这两个对象是否正确描述了经过的生成器的输出?显然是这样。它们对发电机本身至关重要吗?不是真的。

      当然,一个真正的生成器可能会有一个状态(你可以把它称为索引 - 前提是如果它只是一个非负的积分标量你不一定称之为索引;你可以记下它的所有状态,如果它确定性地工作,给它们编号并调用当前状态的数字索引 - 是,大约那个)。他们将始终拥有其状态和返回值的来源。因此,索引和列表可以被视为描述对象行为的抽象。但它们是非常不必要的,它们是真正使用的具体实现细节。

      考虑使用无缓冲的文件阅读器。它从磁盘中检索单个字节并立即生成它。内存中没有真正的列表,只有磁盘上的文件内容(如果我们的文件阅读器连接到网络套接字而不是真正的磁盘驱动器,甚至可能没有,并且Delphi的Oracle在连接的另一端) 。你可以调用文件位置索引 - 直到你读取stdin,它只能是可向前遍历的,因此索引它没有真正的物理意义 - 通过不可靠的协议BTW进行网络连接也是如此。

      像这样。

答案 1 :(得分:0)

1)这是错的;这只是从列表中解释生成器的最简单示例。如果你想到8个皇后问题并且你在程序找到它后立即返回每个位置,我就无法在任何地方识别结果列表。请注意,即使是python标准库(islice() vs. slice()也可以交替使用迭代器,一个不能用列表表示的简单示例是itertools.cycle()

结果2和3也是错误的。