python - enumerate() 会生成生成器对象吗?

标签 python

作为一个完整的 Python 新手,它看起来确实如此。运行 下面...

x = enumerate(['fee', 'fie', 'foe'])
x.next()
# Out[1]: (0, 'fee')

list(x)
# Out[2]: [(1, 'fie'), (2, 'foe')]

list(x)
# Out[3]: []

...我注意到:(a) x 确实有一个 next 方法,好像是 生成器需要,并且 (b) x 只能迭代一次,a this famous python-tag answer 中强调的发电机特性.

另一方面,this question 的两个最受好评的答案 关于如何确定一个对象是否是一个生成器似乎 表示 enumerate() 确实返回生成器。

import types
import inspect

x = enumerate(['fee', 'fie', 'foe'])

isinstance(x, types.GeneratorType)
# Out[4]: False

inspect.isgenerator(x)
# Out[5]: False

... 而第三个 poorly-upvoted answer这个问题似乎表明 enumerate() 确实 实际上返回了一个生成器:

def isgenerator(iterable):
    return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__')

isgenerator(x)
# Out[8]: True

那么发生了什么? x 是不是生成器?是不是某种意义上 “类似发电机”,但不是真正的发电机? Python 的使用是否 鸭子打字意味着上面最终代码块中概述的测试 实际上是最好的吗?

而不是继续写下贯穿我的可能性 头,我会把这个扔给你们中的人,他们会立即 知道答案。

最佳答案

虽然 Python 文档说 enumerate 在功能上等同于:

def enumerate(sequence, start=0):
    n = start
    for elem in sequence:
        yield n, elem
        n += 1

真正的enumerate 函数返回一个iterator,但不是真正的生成器。如果您在创建 enumerate 对象后调用 help(x) 可以看到这一点:

>>> x = enumerate([1,2])
>>> help(x)
class enumerate(object)
 |  enumerate(iterable[, start]) -> iterator for index, value of iterable
 |  
 |  Return an enumerate object.  iterable must be another object that supports
 |  iteration.  The enumerate object yields pairs containing a count (from
 |  start, which defaults to zero) and a value yielded by the iterable argument.
 |  enumerate is useful for obtaining an indexed list:
 |      (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
 |  
 |  Methods defined here:
 |  
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |  
 |  __iter__(...)
 |      x.__iter__() <==> iter(x)
 |  
 |  next(...)
 |      x.next() -> the next value, or raise StopIteration
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __new__ = <built-in method __new__ of type object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T

在 Python 中,生成器基本上是一种特定类型的迭代器,通过使用 yield 从函数返回数据来实现。但是,enumerate 实际上是用 C 语言实现的,而不是纯 Python,因此不涉及 yield。您可以在这里找到来源:http://hg.python.org/cpython/file/2.7/Objects/enumobject.c

关于python - enumerate() 会生成生成器对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23663231/

相关文章:

将项目拆分为模块的 Pythonic 方式?

python - 将anaconda升级到最新版本时出现很多冲突

python - os.walk 无法正确处理路径中的 unicode 字符

python - Django formset UpdateView 不允许我上传文件

python - 删除 HTTP "Connection" header ,Python urllib2

python - 如何在 pandas 中对多值分类变量进行二进制编码?

Python ctypes.string_at 释放行为

python - 将 pandas 数据框转换为具有新键名的字典

python - 如何使用 Selenium Webdriver 在谷歌浏览器扩展中选择不同的选项

python - pySerial:端口仅适用于第一个命令