V2EX 10月14日 20:34
Python 迭代器:实际应用与理论的差距
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了Python中迭代器(iterator)的定义与实际应用。作者指出,尽管迭代器在理论上具有内存优化、接口扩展等诸多优势,但在实际编程中,自定义迭代器的应用场景却鲜有出现,许多示例也显得“滥竽充数”,缺乏实际意义。文章引用了PEP 234中关于迭代器优势的描述,并提出了关于迭代器在实际应用中的具体例子以及开发者是否实现过自定义迭代器的疑问,希望能引发社区的深入讨论,从而理解迭代器在实际开发中的价值。

💡 **迭代器与可迭代对象的定义与区分**:文章首先明确了Python中可迭代对象(定义了`__iter__()`或`__getitem__()`方法)和迭代器(定义了`__iter__()`和`__next__()`方法)的概念。尽管迭代器概念先于生成器,但其核心在于提供一种顺序访问元素的方式,并在迭代过程中管理状态。

📉 **实际应用中的迭代器价值模糊**:作者认为,许多关于迭代器的示例,如Python 3的`range()`,虽然体现了内存节省的优势,但其他自定义迭代器的例子,如`OddEven`类,其功能可以通过更直接的方式实现,使得迭代器的必要性显得不那么突出,引发了对迭代器实际应用意义的质疑。

❓ **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 迭代器 Iterator 可迭代对象 Iterable PEP 234 编程实践
相关文章