程序员入伙书——两种循环

其实咱们早已看到过循环了,只是当时并没有要求大家看明白。

循环,就是让程序反复执行同一段代码。利用计算机速度快,脾气好,不怕麻烦的优势(这几点,人类确实比不上),也省得人们把相似的任务反复书写几百遍。

有两种循环,一种是事先预知要循环多少次的,一种事先不知道。这两种循环,咱们在《程序在干什么?》一章里见过。那里头讲过三个例子,第一个例子是从1加到100,我们都知道要循环100次。第二个例子是九九乘法表,我们知道要重复做9行,每行做N列(N等于当前的行数)。第三个例子是猜平方根,这个就不能实现确实要循环多少次了,只隐约觉得精度好过亿分之一就可以结束。

预知循环次数、知道每次循环时要喂什么数据给程序的,叫做for循环。for的意思是:对于(for)每次循环,使用这些值……

预先不知道循环次数,只知道循环的结束条件的,叫做while循环,意思是:当(while)某条件判断为真的情况下,反复执行这段程序……

其实for循环是while的一个特例,例如那个从1加到100的,下面的两段程序,一个用for,一个用while,得到的结果是一样的:

>>> total = 0
>>> for i in range(1, 101):
	total += i
	
>>> total
5050


>>> total = 0
>>> i = 1
>>> while i <= 100:
	total += i
	i += 1
	
>>> total
5050
>>> 

所以我们先讲while。在Python里,while的用法是:

while 条件判断表达式:
	做这个
	做那个
	东张西望

凹进去的这段程序,只要“条件判断表达式”为真(True),就会被反复执行。上面的累加例子里,只要i小于等于100,累加就会持续下去。

while太简单太直观了,没啥可说的,直接说for吧,for的用法是:

for var in (value_1, value_2, value_3, ..., value_n):
	逛街
	试穿衣服
	讨价还价

凹进去的这段程序,会被执行N次,其中N等于for语句后头那个括号里的数值的个数。每次循环这段程序时,变量var会分别等于括号里的每个值。例如上头的累加例子,range(1, 101)产生了一个序列(1, 2, 3, 4, …, 100),于是for循环里面的total += i就被循环了100次,每次i换一个值,第一次等于1,第二次等于2,……最后一次等于100。

来,玩个好玩的。不需要看懂import math,只需要知道math.sin是求正弦,math.pi等于圆周率3.1415926…就可以了:

>>> import math
>>> for i in range(51):
        print(' ' * round((math.sin(math.pi/25*i) + 1) * 30), '*')

                               *
                                   *
                                      *
                                          *
                                             *
                                                 *
                                                    *
                                                      *
                                                        *
                                                          *
                                                            *
                                                            *
                                                             *
                                                             *
                                                            *
                                                            *
                                                          *
                                                        *
                                                      *
                                                    *
                                                 *
                                             *
                                          *
                                      *
                                   *
                               *
                           *
                        *
                    *
                 *
             *
          *
        *
      *
    *
  *
  *
 *
 *
  *
  *
    *
      *
        *
          *
             *
                 *
                    *
                        *
                           *
                               *
>>> 

哎呀呀,太简单了,又说完一个。不想提前结束怎么办呢?我再说说两个特殊的语句:break和continue。

大家一定注意到,那个猜平方根的程序里,while后面接的不是普通的条件判断表达式,而是True。来,咱们把代码再放到这儿看一下:

print('Please input a number: ', end = '')
n = abs(float(input()))
high = max(1, n)
low = 0
while True:
    result = (high + low) / 2
    if abs(result * result - n) < n * 1E-8:
        break
    if result * result > n:
        high = result
    else:
        low = result
print('Square root of %g is %g' % (n, result))

理论上说,这个循环会永远执行下去,行话叫“死循环”。死循环是程序员常犯的错误之一,当然,故意做成的死循环,也是有的。咱们面前这台计算机,就是在不停地等咱们移动、点击鼠标,敲打键盘……并对每个动作做响应,之后,默默回到原点继续等待。

扯远了,接着说这个平方根程序。大家也看到了,这个程序并未陷入死循环,只跑了二十几遍就退出来了。它是从哪儿退出的呢?细细一瞧就看出端倪了,有一个语句叫做break。

break的意思是,立刻跳出眼前所在的这层循环,程序转向紧跟这个while块的下一句(这个例子里,是执行print)。注意,只跳出一层:如果循环是被嵌套在一个更大的循环里的,break不会跳出更大的那层循环。

再说continue,有时我们需要让程序逐个扫描用户的输入内容,滤掉垃圾信息,只选出有用的部分做处理。“忽略”什么东西的操作一定比“处理”什么东西的操作要简单,我们直观地想这个程序,大约就是这样写的:

while 松子还没嗑完:
        取一个松子
        if 松子 not 空的 and 有开口 and not 发霉:
                把它放在牙槽上
                咬
                把指甲嵌到缝里
                向两边掰开
                把壳扔掉
                把松子吃掉
        else:
                把松子扔掉

上头这个思路是对的,只是你看,if块被缩进去两次,如果嵌套层数很多,缩进的空格就和一行差不多宽了,程序很难读的。另外,大家看到if,总觉得心乱如麻的,怕还有个else在后头等着。为了给自己一种“这个数据纯属垃圾,果断丢弃!下一个!”的干练态度,continue语句就上场了。continue的意思是,忽略此循环体尚未被执行到的部分,果断回到循环的起点,准备下一次循环。刚才的这个代码就可以被写成下面的样子。

while 松子还没嗑完:
        取一个松子
        if 松子 空的 or not 开口 or 发霉了:
                把松子扔掉
                continue    # 下一个!
        把它放在牙槽上
        咬
        把指甲嵌到缝里
        向两边掰开
        把壳扔掉
        把松子吃掉

再强调一次:虽然都是“忽略掉循环体的剩余部分”,break是跳出整个循环体,continue是回到起点准备下一次循环。

break和continue对于while和for都适用。

  • 通告关闭
  • 评论 (4)
    • mileslei
    • 2013年01月3日 10:42上午

    25是对正弦曲线取样的个数。采25个点来画这条曲线,你可以改变一下这个数字看看。
    30是把曲线放大的系数。正弦曲线的取值是-1到1之间,所以我要把这条线抻得宽一些。

    • Lingling
    • 2013年01月2日 5:49下午

    25和30是怎么选出来的?

    • Lingling
    • 2013年01月2日 3:00下午

    加了一段看它出来的是什么,其实中间那个sin不是很懂
    >>> for i in range(51):
    print(round((math.sin(math.pi/25*i) + 1) * 30))
    print(‘ ‘ * round((math.sin(math.pi/25*i) + 1) * 30), ‘*’)

    • Lingling
    • 2012年12月28日 11:41下午

    吃松籽就是我的真实写照

评论关闭