思考 Python
像计算机科学家一样思考
Version 1.1.22
思考 Python
像计算机科学家一样思考
Version 1.1.22
Allen Downey
Green Tea Press
Needham, Massachusetts
Copyright 2008 Allen Downey.
Printing history:
2002 四月: 第一版像计算机科学家一样思考.
2007 八月: 大幅改动,把标题改为像 (Python) 程序员一样思考.
2008 六月: 大幅改动,把标题改为思考 Python:像计算机科学家一样思考.
Green Tea Press
9 Washburn Ave
Needham MA 02492
Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU
Free Documentation License, Version 1.1 or any later version published by the Free Software Foun-
dation; with no Invariant Sections, no Front-Cover Texts, and with no Back-Cover Texts.
The GNU Free Documentation License is available from www.gnu.org or by writing to the Free Soft-
ware Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
The original form of this book is LATEX source code. Compiling this LATEX source has the effect of gen-
erating a device-independent representation of a textbook, which can be converted to other formats
and printed.
The LATEX source for this book is available from http://www.thinkpython.com
前言
0.1 本书的奇怪历史
1999 年一月份的时候,我准备用 Java 教一门介绍性的编程课。在那之前,我已经教了三
次,而且每次我都很失望。这门课的挂课率非常之高,尽管对那些通过的学生来说,整体
的水平也是很低的。
我认为问题的根源之一是教科书。教科书太厚了,掺杂着大量不必要的 Java 细节内容,并
且没有足够高水平的引导去指导学生如何编程。学生们深陷“陷阱门“: 他们起步很轻松,
逐步的学习,突然,大约在第五章的某个位置,困难出现了。学生必须快速的学习大量的
新内容。结果,我不得不把剩下的学期花在挑选一些片段来教学。
课程开始的前两周,我决定自力更生 ---自己编写书。我的目标是:
X 尽量简短. 对学生来说,阅读十页比阅读五十页要好。
X 注意词汇量。我尽量减少使用术语,而且在使用前必须先定义。
X 逐步学习。为了避免陷阱门,我把最难的部分分解成一系列的小步骤。
X 把重心放在编程,而不是编程语言。我采用最少的有用的 Java 语言的语法,忽略其
他的。
我需要一个书名,所以我就临时地把它叫做《像计算机科学家一样思考》
第一版很粗糙,但是很成功。学生们很乐意看它,并且能很好理解我在课堂上讲的难点,
趣点和让他们实践的内容 (这个最重要).
我用 GNU 自由文档许可证发布了这本书,读者们可以自由的复制,修改,发布这本书。
接下来发生的事儿极其的有趣。Jeff Elkner, 居住在弗尼亚的高中老师,改变了我的书,把
它翻译成了 Python。他给我寄了份他翻译的副本,于是乎我就有了一段不寻常的学习
Python 的经历 --通过阅读我自己的书。
Jeff 和我随后修订了这本书,加入了 Chris Meyers 提供的一个案例学习。在 2001 年,我们
共同发布了《像计算机科学家一样思考:Python 编程》, 当然同样是用 GNU 自由文档许可
vi
Chapter 0. 前言
证。通过 Gree Tea Press, 我出版了这本书,并且开始在亚马逊和大学书店卖纸质书。Gree
Tea Press 出版的书可以从这儿获得greenteapress.com
2003 年,我开始在 Olin College 教书。第一次,我开始教 Python。和教授 Java 的情况相
反,学生们不再陷入泥潭,学到了更多,参与了很多有趣的项目,越学越带劲。
在过去的五年里,我一直继续完善这本书,改正错误,提过某些例子的质量,加入一些其
他的材料,特别是练习。在 2008 年,我开始重写这本书 ---同时,剑桥大学出版社的编辑联
系到了我,他想出版本书的下一板。美妙的时刻!
结构就出现了现在的这本书,不过有了一个简洁的名字《思考 Python》。变化有:
X 在每一章末尾加了点调试的部分。这些部分提供了发现和避免 bug 的通用技巧, 也对
Python 的陷阱提出了警告。
X 删除了最后几章关于列表和树实现的内容。虽然,我万分不舍,但是考虑到和本书余
下的部分不协调,只能忍痛割爱。
X 增加了一些案例学习 ---提供了练习,答案和相关讨论的大例子。一些东西是基于
Swampy,这是我为了教学而设计的 Python 程序。Swampy,代码实例和部分答案
可以从这儿获得thinkpython.com.
X 扩展了关于程序构建计划和基本的设计模式的讨论。
X Python 运用的更加地道。虽然这本书仍然是讨论编程的,而不是 Python 本身,但是
现在我不得不承认这本书深受 Python 浸染。
我希望读者们可以享受这本书,也希望帮助你学习程序设计和像计算机科学家一样思考,
哪怕是一丁丁点儿。
Allen B. Downey
Needham MA
Allen Downey 是 Olin College 大学计算机科学与技术系的副教授。
致谢
首先也是最重要的,我要感谢 Jeff Elkner 将我的 Java 教材译为 Python 版本,为此项目奠
基并且向我介绍了 Python 语言,它现在已经是我最的首选编程语言.
感谢 Chris Meyers,向如何像一个计算机科学家思考一书也就是本书的前身贡献了若干内
容.
感谢自由软件基金会开发了 GNU Free Document License 这一授权协议,使我与 Jeff,
Chris 的共事得以成为现实.
感谢 Lulu 的编辑们为本书前身如何像一个计算机科学家思考付出的努力.
感谢所有为此书早期版本做出努力的学生与所有向我寄送更正与建议的贡献者(在后面列
出).
更感谢我妻子 Lisa 为此书,还有绿茶出版,以及其他所有事情做出的工作.
0.1. 本书的奇怪历史
贡献者列表
vii
100 多位目光锐利,头脑灵活的读者在过去的几年中寄给我许多建议与更正。他们的贡献和
热忱对项目建功颇多.
如果你有建议或者更正,也请寄送 email 至 feedback@thinkpython.com. 如果我基於你的
反馈做出了修改,你将被列於此贡献者列表(除非你自己申明愿意被忽略).
如果能够附上出现错误的句子,哪怕是一部分,将有助我进行搜索。页码与章节序号亦可,
不过句子更方便。谢谢。
X Lloyd Hugh Allen 提交了第 8.4 节的一个更正.
X Yvon Boulianne 寄给我第 5 章的一个更正.
X Fred Bremmer 提交了第 2.1 节的一个更正.
X Jonah Cohen 撰写了将 LaTeX 源代码转换为漂亮的 HTML 文件的 Perl 脚本.
X Michael Conlon 提交了第 2 章的一个语法更正与第 1 章的一个文风改善意见,还发起了关於解
释器的技术层面的讨论。
X Benoit Girard 提交了第 5.6 节的一个比较滑稽错误的更正。
X Courtney Gleason 与 Katherine Smith 撰写了 horsebet.py, 用作此书早期版本的一个参考案
例。此程序可以在网上找到。
X Lee Harr 提交了很多更正,因为空间有限无法一一列出。因为贡献较大,其实他可以称作此书
的重要编辑之一。
X James Kaylin 是一个使用此教材的学生,提交了大量的更正。
X David Kershaw 修正了第 3.10 节的 catTwice 函数。
X Eddie Lam 提交了第 1,2,3 章的大量更正。他也修正了 Makefile,使得在第一次运行时可以
生成一个索引。本书的版本计画也由他发起。
X Man-Yong Lee 提交了第 2.4 节的一个例题代码的一个更正。
X David Mayo 指出第 1 章的一个用词不当。
X Chris McAloon 提交了第 3.9 节与第 3.10 节的若干更正。
X Matthew J. Moelter 曾长期关注此书,提交了大量的更正与建议。
X Simon Dicon Montford 报告了第 3 章的一个缺失函数定义错误与若干拼写错误。亦指出第 13
章中 increment 函数的错误。
X John Ouzts 更正了第 3 章中的关於返回值的定义。
X Kevin Parks 针对如何提高此书的发行质量提交了宝贵的评论与建议.
X David Pool 提交了第 1 章的术语表中一个拼写错误,而且给我们打气。
X Michael Schmitt 提交了关於文件於异常章节中的一个更正.
X Robin Shaw 指出了 13.1 中的一个错误(一个范例中使用 printTime 函数但是没有事先定义)。
X Paul Sleigh 找出了第 7 章的一个错误,且发现了 Jonah Cohen 用来从 LaTeX 生成 HTML 页面
的 Perl 脚本中的一个 bug.
X Craig T. Snydal 於 Drew 大学实践此教材。他贡献了数处有用的建议与更正.
X Ian Thomas 与他的学生在一个编程课程中使用此教材。他们是此书后面一半章节最早的实践
者,也提出了大量的更正与建议.
X Keith Verheyden 提交了第 3 章的一个更正.
X Peter Winstanley 给我们指出了第 3 章中一个长期存在的错误。
X Chris Wrobel 贡献了若干关於文件 I/O 与异常章节中的更正.
viii
Chapter 0. 前言
X Moshe Zadka 对此项目做出了难能可贵的贡献. 除了为此书开头部分撰写了辞典范例相关内容,
在整个此书的早期阶段他一直提供指导。
X Christoph Zwerschke 提交了数处更正与教学考虑上的建议, 并向我们解释了 gleich 与 selbe 之
间的差别.
X James Mayer 向我们提交了一大堆的拼写与录入错误,包含这个贡献者列表中的两个.
X Hayden McAfee 指出了两个范例中可能存在的令人困惑的不一致.
X Angel Arnal 是本书的西班牙文版本翻译组成员之一. 他亦找出了英文版本的数处错误.
X Tauhidul Hoque 与 Lex Berezhny 创建了第 1 章插图并提高了其他数处插图的质量.
X Dr. Michele Alzetta 找出了第 8 章的一个错误并且针对 Fibonacci 与 Old Maid 这两个范例提交
了一些从教学方面的评论与建议.
X Andy Mitchell 找出了第 1 章的一个拼写错误与第 2 章的某范例的阙漏之处.
X Kalin Harvey 建议对第 7 章的一处概念澄清并且提交了一些拼写错误.
X Christopher P. Smith 找出了数处拼写错误并且协助我们将此书针对 Python 2.2 做了更新。
X David Hutchins 找出了序中的一个拼写错误.
X Gregor Lingl 於奥地利维也纳的某高中教授 Python, 他正在从事此书的德文翻译并且找出了第
5 章的若干重要错误。
X Julie Peters 找出了前言中的一个拼写错误.
X Florin Oprina 提交了 makeTime 中的一个改善, 一个 printTime 中的更正, 与一个拼写错误.
X D. J. Webre 建议了第 3 章的一个概念澄清.
X Ken 找出了第 8, 9,11 章中的大量错误.
X Ivo Wever 找出了第 5 章中的一个拼写错误并且建议了第 3 章中的一个概念澄清.
X Curtis Yanko 建议了第 2 章中的一个概念澄清.
X Ben Logan 提交了大量的拼写错误与若干将此书转换为 HTML 格式的错误。
X Jason Armstrong 指出了第 2 章一处语法阙漏.
X Louis Cordier 指出第 16 章某处代码与文字不相符合.
X Brian Cain 建议了数处第 2 章与第 3 章的若干概念澄清.
X Rob Black 提交了大量更正, 包含某些针对 Python 2.2 的修改.
X Jean-Philippe Rey 来自於巴黎的 Ecole Centrale,提交了大量的补丁, 包含某些针对 Python 2.2
的修改与一些有想法的改善.
X Jason Mader 来自於 George Washington 大学提交了大量的有用的建议与更正.
X Jan Gundtofte-Bruun 指出一个语法错误.
X Abel David 与 Alexis Dinno 提醒我们 ``matrix'' 的复数形式为 ``matrices'', 而非 ``matrixes''. 此
错误存在於本书中有数年之久,但是两位读者在同一天向我们指出了,不可不谓奇。
X Charles Thayer 指出了数处语法错误。
X Roger Sperberg 指出了第 3 章某处逻辑有误.
X Sam Bull 指出了第 2 章某处令人困惑的段落.
X Andrew Cheung 指出了两处使用之后才定义的错误。
X C. Corey Capel 指出了一个语法错误与一个拼写错误.
X Alessandra 帮助我们澄清了某些概念.
X Wim Champagne 在辞典范例中指出一处错误.
X Douglas Wright 指出了 arc 中的一个除法相关错误.
X Jared Spindor 指出一些语法错误.
X Lin Peiheng 提交了大量的非常有益的建议.