返回介绍

第 14 章 可迭代的对象、迭代器和生成器

发布于 2024-02-05 21:59:47 字数 1737 浏览 0 评论 0 收藏 0

当我在自己的程序中发现用到了模式,我觉得这就表明某个地方出错了。程序的形式应该仅仅反映它所要解决的问题。代码中其他任何外加的形式都是一个信号,(至少对我来说)表明我对问题的抽象还不够深——这通常意味着自己正在手动完成的事情,本应该通过写代码来让宏的扩展自动实现。1

——Paul Graham2
Lisp 黑客和风险投资人

1摘自一篇博客文章,“Revenge of the Nerds”(“书呆子的复仇”)。

2Paul Graham 的文集《黑客与画家:来自计算机时代的高见》已由人民邮电出版社出版,书号:978-7-115-32656-0。——编者注

迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。本章说明 Python 语言是如何内置迭代器模式的,这样就避免了自己手动去实现。

与 Lisp(Paul Graham 最喜欢的语言)不同,Python 没有宏,因此为了抽象出迭代器模式,需要改动语言本身。为此,Python 2.2(2001 年)加入了 yield 关键字。3 这个关键字用于构建生成器(generator),其作用与迭代器一样。

3Python 2.2 的用户可以使用 from __future__ import generators 指令获取 yield 关键字;在 Python 2.3 中,yield 关键字默认可用。

 所有生成器都是迭代器,因为生成器完全实现了迭代器接口。不过,根据《设计模式:可复用面向对象软件的基础》一书的定义,迭代器用于从集合中取出元素;而生成器用于“凭空”生成元素。通过斐波纳契数列能很好地说明二者之间的区别:斐波纳契数列中的数有无穷个,在一个集合里放不下。不过要知道,在 Python 社区中,大多数时候都把迭代器生成器视作同一概念。

在 Python 3 中,生成器有广泛的用途。现在,即使是内置的 range() 函数也返回一个类似生成器的对象,而以前则返回完整的列表。如果一定要让 range() 函数返回列表,那么必须明确指明(例如,list(range(100)))。

在 Python 中,所有集合都可以迭代。在 Python 语言内部,迭代器用于支持:

for 循环

构建和扩展集合类型

逐行遍历文本文件

列表推导、字典推导和集合推导

元组拆包

调用函数时,使用 * 拆包实参

本章涵盖以下话题:

语言内部使用 iter(...) 内置函数处理可迭代对象的方式

如何使用 Python 实现经典的迭代器模式

详细说明生成器函数的工作原理

如何使用生成器函数或生成器表达式代替经典的迭代器

如何使用标准库中通用的生成器函数

如何使用 yield from 语句合并生成器

案例分析:在一个数据库转换工具中使用生成器函数处理大型数据集

为什么生成器和协程看似相同,实则差别很大,不能混淆

首先来研究 iter(...) 函数如何把序列变得可以迭代。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文