V2EX 10月15日 09:11
Python 迭代器:深入理解与实际应用
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文旨在深入探讨Python中的迭代器概念及其在实际应用中的价值。作者在多年编程实践中发现,自定义迭代器的实际应用场景并不常见,且许多教程中的示例显得“滥竽充数”。文章首先明确了可迭代对象和迭代器的定义,并引用了Python 3的range()作为节省内存的优点示例。随后,通过一个自定义的OddEven类作为反例,说明了部分迭代器实现的“无实际意义”的困境。文章的核心在于,作者引用PEP 234中的迭代器优点,并向社区征集具体的应用实例和实际开发中自定义迭代器的经验,以期厘清迭代器在实际开发中的真正作用。

💡 **迭代器与可迭代对象的核心定义**:文章明确指出,可迭代对象(iterable)是指实现了`__iter__()`或`__getitem__()`方法的对象;而迭代器(iterator)则需同时实现`__iter__()`和`__next__()`方法。这一基础定义是后续讨论的基石,帮助读者区分两者并理解其工作机制。

🚀 **迭代器在内存优化中的实际价值**:以Python 3的`range()`函数为例,文章强调了迭代器在不一次性生成整个序列(如列表)的情况下,能够显著节省内存。这对于处理大规模数据时尤为重要,避免了因内存不足导致程序崩溃或性能下降。

🤔 **对“滥竽充数”的迭代器实现的质疑与探讨**:文章通过一个自定义的`OddEven`类示例,指出了在某些情况下,迭代器的实现可能显得“画蛇添足”,功能可以通过更简单的方式实现,缺乏实际应用价值。这引发了对如何判断迭代器是否真正必要性的思考,并开启了对PEP 234所列优点的具体化探讨。

🌟 **PEP 234中迭代器优点的实际化解读**:文章引用了PEP 234中关于迭代器的多项优点,如“可扩展的迭代器接口”、“对列表迭代的性能优化”、“大幅度提升字典迭代性能”等,并向社区征集具体的实例,旨在将这些抽象的理论优势转化为可理解、可感知的实际应用场景,帮助开发者更好地认识迭代器的强大之处。

🤝 **寻求社区实践经验,共探迭代器应用边界**:作者坦诚自己在实际开发中很少遇到自定义迭代器的应用,并积极邀请社区成员分享他们在实际项目中实现迭代器的具体案例。这种开放式的交流方式,旨在汇聚更广泛的视角和经验,共同探索迭代器在各种复杂场景下的真正价值和最佳实践。

概述

最近在梳理 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 classoddeven = OddEven("0123456789")print("".join(c for c in oddeven))  # 0246813579oddeven = OddEven("ABCD")  # or manually...it = iter(oddeven)  # this calls oddeven.__iter__ internallyprint(next(it))  # Aprint(next(it))  # Cprint(next(it))  # Bprint(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/

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Python 迭代器 可迭代对象 PEP 234 编程实践 内存优化 Iterator Iterable Programming Practice Memory Optimization
相关文章