Skip to content

Commit d26cbed

Browse files
author
wolf
committed
chapter07
1 parent 6a06751 commit d26cbed

File tree

1 file changed

+241
-1
lines changed

1 file changed

+241
-1
lines changed
Lines changed: 241 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,241 @@
1-
\chapter{迭代}
1+
\chapter{迭代器}
2+
\index{iteration 迭代器}
3+
4+
\section{多重赋值}
5+
\index{statement!assignment}
6+
\index{mutiple assignment 多重赋值}
7+
8+
你可能已经发现,给一个变量多次赋值是合法的。一次新的赋值使得已存在的变量指向一个新值(当然也就不指向原来的值)。
9+
10+
\beforeverb
11+
\begin{verbatim}
12+
bruce = 5
13+
print bruce,
14+
bruce = 7
15+
print bruce
16+
\end{verbatim}
17+
\afterverb
18+
19+
程序的输出是{\tt 5 7},因为第一次{\tt bruce}被输出时,它的值是5,第二次是7。
20+
第一个{\tt print}语句末尾的逗号抑制了换行,这也是为什么两个输出在同一行的原因。
21+
22+
\index{newline 换行}
23+
24+
下图是多重赋值的状态图:
25+
26+
\index{state diagram}
27+
\index{diagram!state}
28+
29+
\beforefig
30+
\centerline{\includegraphics{figs/assign2.eps}}
31+
\afterfig
32+
33+
对于多重赋值,很有必要分清赋值操作符和关系运算符中的等号。因为Python使用
34+
等于号({\tt =})来表示赋值。很容易,误把这样的语句{\tt a = b}当作判断相等的语句,
35+
实际不是的!\\
36+
37+
\index{相等与赋值}
38+
39+
40+
第一,相等是对称关系,赋值不是。比如,在数学中,如果$a = 7$, 那么$7 =
41+
a$。但在Python中,语句{\tt a = 7}是合法的,{\tt 7 = a}是非法的。\\
42+
43+
另外,在数学中,相等语句总是要么为真要么为假。如果,$a = b$,则,$a$
44+
是等于$b$。在Python中,赋值语句可以使得两个变量相等,但是他们不总是保持相等:
45+
46+
\beforeverb
47+
\begin{verbatim}
48+
a = 5
49+
b = a # a and b are now equal
50+
a = 3 # a and b are no longer equal
51+
\end{verbatim}
52+
\afterverb
53+
%
54+
55+
第三行改变了{\tt a}的值,但是没有改变{\tt b}的值。所以他们不再相等。
56+
57+
尽管多重赋值通常是有益的,使用时也要小心。如果变量的值经常改变,代码
58+
会变得很脑阅读和调试。
59+
60+
\section{更新变量}
61+
\label{update}
62+
63+
\index{update 更新}
64+
\index{variable!updating}
65+
66+
多重赋值的最常见的形式之一就是更新(update),变量的新值依赖于原有值。
67+
68+
\beforeverb
69+
\begin{verbatim}
70+
x = x+1
71+
\end{verbatim}
72+
\afterverb
73+
74+
含义是:获取{\tt x}的当前值,加一,然后用新值更新变量{\tt x}。
75+
76+
如果试着更新一个不存在的变量,将会得到一个错误,因为Python在把值赋给
77+
{\tt x}之前会计算右边的值。
78+
79+
\beforeverb
80+
\begin{verbatim}
81+
>>> x = x+1
82+
NameError: name 'x' is not defined
83+
\end{verbatim}
84+
\afterverb
85+
%
86+
87+
在更新一个变量之前,必须得初始化(initialize)它,通常的做法就是一个
88+
简单的赋值。
89+
90+
\index{initialization (before update) (更新前)初始化}
91+
92+
\beforeverb
93+
\begin{verbatim}
94+
>>> x = 0
95+
>>> x = x+1
96+
\end{verbatim}
97+
\afterverb
98+
%
99+
100+
仅仅通过加一来更新变量叫做增量 (increment);减一叫做减量(decrement)。
101+
102+
\index{increment 增量}
103+
\index{decrement 减量}
104+
105+
\section{{\tt while 语句}}
106+
107+
\index{statement!while}
108+
\index{while loop while循环}
109+
\index{loop!while}
110+
\index{iteration 迭代}
111+
112+
计算机通常被用来自动完成重复性的任务。计算机很擅长于重复相同或相似的任务。人类却恰恰相反\footnote{太枯燥了,回顾一下小学时,老师天天要求抄生字......}。
113+
114+
我们已经看到两个程序,{\tt countdown}和\verb"print_n",它们使用递归
115+
实现重复,这也可以乘坐迭代{\bf iteration}。因为迭代是如此的常见,以致
116+
于Python提供了几个特有的方式来简化使用。其中之一就是我们在\ref{重复}
117+
部分看到的{\tt for}语句。我们不久将回来重新研究它。\\
118+
119+
另外一个就是{\tt while}语句。这里是一个使用{\tt while}语句的{\tt coutdown}版本。
120+
121+
\beforeverb
122+
\begin{verbatim}
123+
def countdown(n):
124+
while n > 0:
125+
print n
126+
n = n-1
127+
print 'Blastoff!'
128+
\end{verbatim}
129+
\afterverb
130+
131+
我们几乎可以把{\tt while}语句当成英语来读了。含义是:当{\tt n}大于0时
132+
,显示{\tt n}的值,并把{\tt n}的值减1。当{\tt n}的值为0的时候,显示{\tt Blastoff!}。
133+
134+
\index{flow of execution 执行流}
135+
136+
更正式地,下面的是{\tt while}语句的执行流。
137+
138+
\begin{enumerate}
139+
140+
\item 计算条件的值,产生结果{\tt True}或者{\tt False}。
141+
142+
\item 如果条件为假,退出{\tt while循环},继续执行下一条语句。
143+
144+
\item 如果条件为真,执行语句体里的语句,然后回到步骤一。
145+
146+
\end{enumerate}
147+
148+
执行流的类型称作是循环(loop)的原因是因为第三步循环返回至第一步。
149+
150+
\index{condition 条件}
151+
\index{loop 循环}
152+
\index{body 体}
153+
154+
循环体应该改变一个或多个变量的值,使得最终条件为假,循环终止。否则,
155+
循环将永远重复,也就产生了无限循环(infinite loop)。计算机科学家的
156+
一个永远的谈资就是看到洗发水的说明"泡沫,漂洗,重复",是一个无限循环。
157+
158+
\index{infinite loop 无限循环}
159+
\index{loop!infinite}
160+
161+
在{\tt countdown}的例子里,我们可以证明循环一定会终止,因为我们知道
162+
{\tt n}的值是有限的,并且每一次循环{\tt n}的值都会减小,最终,{\tt n}的值肯定是0。在其他情况下,就不一定这么容易辨别了:
163+
164+
beforeverb
165+
\begin{verbatim}
166+
def sequence(n):
167+
while n != 1:
168+
print n,
169+
if n%2 == 0: # n is even
170+
n = n/2
171+
else: # n is odd
172+
n = n*3+1
173+
\end{verbatim}
174+
\afterverb
175+
176+
这个循环的条件是{\tt n != 1},所以循环会一直执行到{\tt n}是{\tt 1},
177+
此时条件为假。\\
178+
179+
每一次循环,程序输出{\tt n}的值,然后检查是否为偶数或奇数。如果是偶数
180+
{\tt n}就除以2。如果为奇数,{\tt n}的值就被{\tt n*3+1}代替。比如,
181+
如果传递3给{\tt sequence},产生的结果是3, 10, 5, 16, 8, 4, 2, 1。
182+
183+
因为{\tt n}时增时减,没有一个明显的办法确定{\tt n}是否会为1,也就是
184+
程序是否会正常终止。对于某些特别的{\tt n},我们可以证明终止。比如,
185+
如果{\tt n}的值是2的倍数,每次循环时{\tt n}的值,都是偶数直到为1。
186+
前面的例子从16开始都是这种情况。
187+
188+
\index{Collatz conjecture Collatz猜想}
189+
190+
困难的是我们是否可以证明对所有的正整数,程序都能终止。迄今为止\footnote{参看\url{wikipedia.org/wiki/Collatz_conjecture}.}没有人可以证明
191+
可以,也没有人证明不可以。
192+
193+
\begin{ex}
194+
重写\ref{递归}部分的\verb"print_n"函数,要求使用迭代器,而不是递归。
195+
\end{ex}
196+
197+
\section{{\tt break}语句}
198+
\index{break statement break语句}
199+
\index{statement!break}
200+
201+
有时,直到执行到循环体里面的时候,才直到需要跳出循环。此时,我们可以
202+
使用{\tt break}语句跳出循环。
203+
204+
比如,假设一直想从用户那里得到输入,直到用户输入{\tt done}。我们可以
205+
这么写:
206+
207+
\beforeverb
208+
\begin{verbatim}
209+
while True:
210+
line = raw_input('> ')
211+
if line == 'done':
212+
break
213+
print line
214+
215+
print 'Done!'
216+
\end{verbatim}
217+
\afterverb
218+
219+
循环条件为{\tt True},也就是永远为真,所以循环直到遇到break statement
220+
才终止执行。
221+
222+
每次循环,用尖括号提示用户。如果用户输入{\tt done},{\tt break}语句
223+
终止了循环。否则,程序输出用户输入的内容,会到循环的顶部。下面是一个例子:
224+
225+
\beforeverb
226+
\begin{verbatim}
227+
> not done
228+
not done
229+
> done
230+
Done!
231+
\end{verbatim}
232+
\afterverb
233+
%
234+
235+
这种使用{\tt while}循环的方式很常见,因为我们可以在循环的任何地方检查
236+
条件(不仅仅是在顶部),同时也积极的表达了结束的条件(当这个发生时,终止),而不是消极地("一直运行,直到这个发生")。
237+
238+
\section{平方根}
239+
\index{square root}
240+
241+

0 commit comments

Comments
 (0)