【问题标题】:Is there a way to distinguish this iterator from this generator?有没有办法区分这个迭代器和这个生成器?
【发布时间】:2020-09-14 08:06:24
【问题描述】:

我知道这个问题:

Difference between Python's Generators and Iterators

它的范围更广,技术基础更少。而且没有一个答案被选中。我还通读了这些答案,除了一个可能的例外,没有找到我想要的东西。我想问一个更准确的问题来帮助我理解一些细节。

我之前问过这个问题:

What is the difference between a python itterator and a python generator?

也许标题或我提出问题的方式具有误导性,因为我得到的回答并不符合我的意图,而且问题在几秒钟内就结束了。

所以我会在这里澄清一下。

考虑以下代码:

p = [k for k in range(1,1000)]
i = iter(p)
g = (k for k in p)

是否可以对 i 和 g 进行一些操作来区分这两种结构。我可以用 i 做而我不能用 g 做的事情,诸如此类。它们的类型以列表迭代器与生成器对象的形式出现,但我不清楚这对人们可以用它做什么或它的效率有任何实际影响。我特意先构建了列表,以强调预先或按需生成列表的问题不是问题所在。

目前,我怀疑更一般的问题的答案是这样的 - 生成器是迭代器的一个特例,无论你可以使用推导式或产量来构造生成器,都可以通过显式编写相应的迭代器来完成。使用生成器而不是迭代器的理由是有时它更容易编写。


后来我发现这个问题引发了对该主题的一些很好的阐述。

How to write a generator class?

【问题讨论】:

  • 嗯,是的,添加了生成器作为创建迭代器的便捷方式。它们也很有表现力,通常提供更简洁的代码。生成器也可以充当协程,因此您可以将.send 值放入生成器...如果您只是想区分类型,可以使用Generator = type((None for _ in range(0))) 然后只需检查isinstance(some_object, Generator)
  • Here's 一些不错的读物。
  • 谢谢大家。我想声明一下,我理解并使用了几种语言中涉及的概念。我一直在寻找直截了当的技术细节——因为我似乎在翻阅似乎花费大量时间解释概念而不是实现的文档时无处可去。恕我直言。

标签: python iterator generator


【解决方案1】:

g 支持send,就像所有生成器一样,而i 不支持。 (sending 到 g 不是有用,但你可以做到。)

>>> g.send(None)
1
>>> i.send(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list_iterator' object has no attribute 'send'

您还可以将throw 异常转换为gclose 它,这是i 无法做到的。

i 可以腌制,而g 不能。

除此之外,您还可以进行各种显式检查和自省来区分它们。检查类型、检查str 输出、查找仅存在于其中一个或另一个上的属性(如g.gi_frame)等。

其中大部分是实现细节或附带的,而不是您应该将其视为“生成器和迭代器之间的区别”。生成器是一种迭代器。

【讨论】:

    【解决方案2】:

    以下是文档摘录:

    4.5.1 生成器类型:
    Python 的生成器提供了一种方便的方式来实现迭代器协议。

    及以后:

    6.2.9。屈服表达式:
    当调用生成器函数时,它会返回一个称为生成器的迭代器。

    => 生成器函数创建迭代器

    接下来的段落给出了生成器的附加方法:

    6.2.9.1。生成器迭代器方法
    本小节介绍生成器迭代器的方法。

    generator.__next__(): ...

    iterator.next()的行为相同

    generator.send(value)
    恢复执行并将值“发送”到生成器函数...

    `generator.throw(type[, value[, traceback]])``
    在生成器暂停时引发类型类型异常,并返回生成器函数产生的下一个值...

    generator.close()
    在生成器函数暂停的位置引发 GeneratorExit...

    这意味着生成器是具有一些附加方法的迭代器的特例。

    【讨论】:

    • 谢谢,我也喜欢这个答案——但必须做出选择。这里的回答肯定让我对这件事有了清晰的认识。
    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 2010-11-04
    • 2018-07-15
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    相关资源
    最近更新 更多