codists:
概述
最近在梳理 iterator ,不得不说, 即使自己写了很多年的代码,我仍然没有在实际应用中看到自定义的迭代器。即使读了很多书,但是这些书中的示例大多是滥竽充数,不具备实际应用意义。所以顺着网线爬上 V 站请教各位。
可迭代对象 & 迭代器定义
可迭代对象
如果一个对象定义了 __iter__()
方法或定义了 __getitem__()
方法,那么这样的对象称为可迭代对象(iterable)。
迭代器
如果一个对象定义了 __iter__()
方法和 __next__()
方法,那么这样的对象称为迭代器(iterator)。
注:
1.后续的讨论都是基于以上两个定义。
2.因迭代器常和可迭代对象结合使用,故引如可迭代对象这一概念,但迭代器的概念先于生成器(generator),在后续的讨论中请勿涉及生成器。
一些示例
示例 1
python 3 的 range() 是一个可迭代对象,其实现使用了迭代器。使用迭代器后不是直接生成列表,节省了内存,体现了迭代器的应用意义。
示例 2
《 Learn Python Programming(4th)》 第 246 页:
class OddEven:
def __init__(self, data):
self._data = data
self.indexes = list(range(0, len(data), 2)) + list(range(1, len(data), 2))
def __iter__(self):
return self
def __next__(self):
if self.indexes:
return self._data[self.indexes.pop(0)]
raise StopIteration
# Testing the OddEven class
oddeven = OddEven("0123456789")
print("".join(c for c in oddeven)) # 0246813579
oddeven = OddEven("ABCD") # or manually...
it = iter(oddeven) # this calls oddeven.__iter__ internally
print(next(it)) # A
print(next(it)) # C
print(next(it)) # B
print(next(it)) # D
该示例虽然创建了一个迭代器,但就功能而言其实就是“将奇数位置的字符放在前半段,将偶数位置的字符放在后半段”,完全没有必要使用迭代器。关于迭代器的实力,本人看到的大多是这样的——毫无实际应用意义,令人深恶痛绝!
问题
问题 1
PEP 234 中写到 iterator 的 virtues 有:
- It provides an extensible iterator interface.
- It allows performance enhancements to list iteration.
- It allows big performance enhancements to dictionary iteration.
- It allows one to provide an interface for just iteration without pretending to provide random access to elements.
- It is backward-compatible with all existing user-defined classes and extension objects that emulate sequences and mappings, even mappings that only implement a subset of {
__getitem__
, keys
, values
, items
}.
- It makes code iterating over non-sequence collections more concise and readable.
中译版:
如果包含该提案的所有部分,则会以一致且灵活的方式解决许多问题。其主要优点包括以下四点——不,五点——不,六点
- 它提供了一个可扩展的迭代器接口。
- 它允许对列表迭代进行性能优化。
- 它允许对字典迭代进行大幅度性能提升。
- 它允许为仅迭代提供接口,而无需假装提供对元素的随机访问。
- 它与所有现有的用户定义类和模拟序列和映射的扩展对象向后兼容,即使是仅实现了 {
__getitem__
, keys
, values
, items
} 子集的映射。
- 它使遍历非序列集合的代码更加简洁易读。
上面所列出的优点较抽象,各位能否提供一些具体的例子?
问题 2
各位在实际应用中是否自己实现过迭代器?如果有麻烦提供一些例子。
参考资料
[1] Python Document Glossary ,iterator: https://docs.python.org/3/glossary.html#term-iterator
[2] PEP 234 – Iterators: https://peps.python.org/pep-0234
[3] PEP 234 – 迭代器: https://peps.pythonlang.cn/pep-0234/