Python 3引入了类似生成器的对象,该对象将在调用range()
和zip()
时返回。返回的对象就像生成器一样,可以被迭代一次,但是不能很好地“打印”,就像enumerate()
返回参数一样。
然而,令我感到困惑的是,它们是不同的对象类型,不属于types.GeneratorType
,或者至少这是types
模块所显示的。一个可以运行的功能期望发电机不会检测到它们。他们的继承是什么?它们是否属于主要的“生成器”结构,以便它们例如可以与其他发电机一起被识别?
import types
a = [1,2,3]
b = [4,5,6]
# create some generator-type objects
obj_zip = zip(a,b)
obj_enu = enumerate(a)
obj_r = range(10)
print(type(obj_zip))
print(type(obj_enu))
print(type(obj_r))
# checking against types.GeneratorType returns False
print(isinstance(obj_zip,types.GeneratorType))
print(isinstance(obj_enu,types.GeneratorType))
print(isinstance(obj_r,types.GeneratorType))
# checking against their own distinct object types returns True
print(isinstance(obj_zip,zip))
答案 0 :(得分:5)
types.GeneratorType
生成器迭代器对象的类型,由生成器函数创建。
生成器功能是该语言中的特定功能;它表示使用yield
或yield from
的函数(或生成器表达式,它们只是内联生成器函数的简写)。它是迭代器集的子集(可以调用next()
的所有事物以获取新值),又是迭代器的子集(可以调用iter()
的所有事物得到一个迭代器;迭代器本身就是可迭代的,其中iter(iterator)
充当标识函数)。
基本上,如果您要测试“是否可以对此进行循环?”,请测试isinstance(obj, collections.abc.Iterable)
。如果您正在检查“这是一个穷举的迭代器?” (也就是说,我会通过遍历它来耗尽它吗?),测试isinstance(obj, collections.abc.Iterator)
或使用基于鸭型的方法,测试iter(obj) is obj
(迭代器上的不变式 require iter(iterator)
不变地产生原始迭代器对象。
请注意,range
不是生成器或迭代器。根据{{3}}:
成为不可变序列类型意味着是可迭代的,仅此而已。通常将其当作迭代器使用,这一事实是无关紧要的。如果它是一个迭代器,那么这里的第二个循环将永远不会执行:
r = range(3)
for i in r:
print("First", i)
for i in r:
print("Second", i)
但它工作得很好,因为对iter(r)
的每个(隐式)调用都会基于相同的底层itera ble返回一个 new itera tor 。
答案 1 :(得分:0)
文档说,枚举在功能上等同于生成器。实际上,它是用C实现的,并返回一个迭代器,而不是Does enumerate() produce a generator object中描述的生成器。 生成器和可迭代对象几乎相同。 Difference between Python's Generators and Iterators中对此进行了详细说明。
我假设您正在尝试解决一个实际的问题,例如找出是否可以迭代某些事物。为了解决该问题,您可以测试某物是否为collections.Iterable
的实例。
a = enumerate([1,2,3])
isinstance(a, collections.Iterable)
>>> True
答案 2 :(得分:0)
并不是完整的答案(ShadowRanger answer已经解释了所有内容),而只是声明$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
import pandas
pandas.read_csv('ccf_online_stage1_train.csv', nrows=11429827)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 678, in parser_f
return _read(filepath_or_buffer, kwds)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 446, in _read
data = parser.read(nrows)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1051, in read
df = DataFrame(col_dict, columns=columns, index=index)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/frame.py", line 348, in __init__
mgr = self._init_dict(data, index, columns, dtype=dtype)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/frame.py", line 459, in _init_dict
return _arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/frame.py", line 7364, in _arrays_to_mgr
return create_block_manager_from_arrays(arrays, arr_names, axes)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/internals.py", line 4872, in create_block_manager_from_arrays
blocks = form_blocks(arrays, names, axes)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/internals.py", line 4918, in form_blocks
int_blocks = _multi_blockify(items_dict['IntBlock'])
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/internals.py", line 4995, in _multi_blockify
values, placement = _stack_arrays(list(tup_block), dtype)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/core/internals.py", line 5037, in _stack_arrays
stacked = np.empty(shape, dtype=dtype)
MemoryError
确实是非常有限的类型,如types.GeneratorType
来源所示:
types.py
它仅限制生成器函数的类型。其他“类似于发电机”的对象不使用def _g():
yield 1
GeneratorType = type(_g())
,因此它们不是匹配项。