【问题标题】:Methods that take iterators instead of iterables [closed]采用迭代器而不是迭代器的方法[关闭]
【发布时间】:2017-03-12 10:48:21
【问题描述】:

关于迭代器和可迭代对象(仅我的观察,如果我错了请纠正我):

  • 大多数(数组类型的)构造函数将迭代器作为质量构造函数
  • 迭代器是显式创建的;或使用x in x for....
  • 许多方法(主要是itertools)返回迭代器(因为它们的工作是迭代?)
  • 采用可迭代对象的方法采用迭代器。 在所有情况下都是这样吗?
  • 采用迭代器的方法不会采用可迭代对象(反向不正确)
  • 唯一显式采用迭代器的方法似乎是next(..

问题:

  • 还有其他采用迭代器的方法吗?

  • 用语法制作迭代器的其他方法是什么?例如:x in x for...

  • 为什么 python 的创建者让next(.. 成为唯一采用迭代器的方法?他们可以很容易地将其变成一个带有额外参数(条件)的可迭代方法?

【问题讨论】:

    标签: python list python-3.x iterator


    【解决方案1】:

    围绕迭代器和可迭代对象的语言有点令人困惑。主要的混淆来自术语“可迭代”,它可能是也可能不是“迭代器”的超集,具体取决于它的使用方式。

    我是这样分类的:

    iterable 是可以迭代的任何对象。也就是说,它有一个返回迭代器的__iter__() 方法,或者它可以用整数索引(当它们超出范围时引发IndexError 异常),这让Python 可以自动为它构建一个迭代器。这是一个非常广泛的类别。

    迭代器是遵循迭代器协议的对象。它有一个 __next__() 方法(在 Python 2 中拼写为 next)产生下一个项目,或者如果没有更多可用值则引发 StopIteration 异常。迭代器还必须有一个返回自身的__iter__() 方法,因此所有迭代器也是可迭代的(因为它们符合上面给出的“可迭代”的定义)。

    non-iterator iterable 是任何 迭代器的可迭代对象。这通常是人们使用术语“可迭代”而不是“迭代器”时的意思。在许多情况下,一个更好的术语可能是“序列”,但这更具体一些(一些非序列对象是非迭代器可迭代对象,例如允许对其键进行迭代的字典)。此类对象的重要特点是您可以对它们进行多次迭代,并且迭代器彼此独立工作。

    所以尝试回答您的具体问题:

    很少有充分的理由让任何函数专门需要一个迭代器。通常可以通过在参数上调用iter() 来获取迭代器,或者通过使用在幕后创建迭代器的for 循环来使函数与任何类型的可迭代参数一样工作。

    反过来就不一样了。如果一个函数需要一个非迭代器可迭代,它可能需要对参数进行多次迭代,因此迭代器将无法正常工作。 Python 标准库(和内置函数)中的函数很少有这样的限制。如果他们需要对一个可迭代参数进行多次迭代,他们通常会在开始时将其转储到序列类型(例如列表)中,如果它已经不是序列的话。

    许多函数返回迭代器。例如,所有生成器对象都是迭代器(生成器函数返回的对象和生成器表达式创建的对象)。文件对象也是迭代器(尽管它们稍微违反了迭代器协议,因为您可以在它们耗尽后使用它们的seek() 方法重新启动它们)。 itertools 模块中的所有函数和类型都返回迭代器,但像 map() (在 Python 3 中)这样的一些内置函数也是如此。

    next() 函数确实不寻常,因为它特别需要一个迭代器。这是因为它被定义为迭代协议本身的一部分。它完全等同于在迭代器上调用__next__() 方法,只是更易于阅读。它还有一个双参数形式,可抑制 StopIteration 异常,否则如果迭代器用尽,则会引发该异常(它返回 default 参数)。

    【讨论】:

    • 感谢您的详尽解释。只是为了澄清,列表/元组/范围是序列类型。不是常规可迭代,而是非迭代可迭代。 next(.. 采用迭代器,它也是一个可迭代的。但它不同于另一种类型的iterable(非iterator iterable)=sequence=list/tuple/range。 (其他差异的具体细节在你的 cmets 中)还有更多,可迭代,泛化:有 __iter__() ?
    • 是的,我想你已经明白了。可迭代是最通用的术语。有些可迭代对象是迭代器,有些则不是。我称那些不是“非迭代器可迭代对象”,但许多人只是称它们为“可迭代对象”导致混淆(因为不清楚它们是指更笼统的术语还是更具体的非迭代器子类别)。跨度>
    猜你喜欢
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2014-10-28
    • 1970-01-01
    • 2012-11-14
    • 2016-07-21
    • 2014-05-17
    相关资源
    最近更新 更多