一个程序由一系列语句构成,其中的语句可分为简单语句和复合语 
句。简单语句包括赋值语句、输入输出语句和表达式语句等。复合语句 
包括条件语句和循环语句等,按照一定的方式控制简单语句的运行。 
程序结构分为 3 种:顺序结构、分支结构和循环结构。 
3.1 顺序结构 
一个程序由一系列语句构成,程序运行时按照语句顺序逐个执行。 
例如,以下是包括输入、输出和赋值语句的程序: 
"""This is a one line docstring: Compute BMI for a person""" 
""" This is a multi-line docstring: 
input weight in kg and height in m, 
compute BMI and print it out. 
""" 
w = float(input('type your weight in kg:')) # 提示用户输出体重 
h = float(input('type your height in m:')) # 提示用户输入身高 
bmi = w / h**2 # 计算bmi 
print('Your BMI is', round(bmi,1)) # 显示结果 
以上程序是包含 4 个简单语句的顺序结构程序。一个顺序结构程 
序中的语句也可以是更复杂的语句,如后面将看到的条件语句或者循环 
语句。
简单语句通常由一行构成。复合语句通常由多行构成。本节介绍几 
种常用的简单语句。 
3.1.1 简单赋值语句 
一个赋值语句 (assignment statement) 的作用是设置或者修改一个 
变量的值,其伪代码格式为 var ← expr,在 Python 中的格式为 
var = expr
61 
其中 var 是变量名,expr 是一个表达式。该语句被执行时,先计算 expr 的值,然后令 
var 表示该值,或者说 var 指向 expr 表示的对象,或者说将 expr 的值绑定于 var。例 
如,图 3.1 表示赋值语句 x = 3 完成后,x 指向数据对象 3。 
图 3.1 赋值语句及其内存 
注意,这里的 var 可以是任何符合变量命名规则的标识符。程序设计语言通常规定 
任何字母或者下画线开始的字母、数字和下画线构成的串都可以作为变量名,但保留字 
除外,而且中间不能有空格。 
不同变量可以指向同一个对象,如图 3.2 所示。一个变量的值可以被重置,如图 3.3 
所示。 
图 3.2 不同变量指向同一个对象 
图 3.3 重置一个变量的值 
那么下列语句序列执行完后,变量 x 和 y 的值各是什么呢? 
>>> x = 3 
>>> y = x 
>>> x = x + 1 
结果是,x 的值为 4,y 的值仍然是 3。赋值语句 x = x + 1 并没有修改 x 原指向的对 
象 3,而是构造了一个新对象 4,并让 x 指向新的对象,而 y 的值不变,如图 3.4 所示。 
图 3.4 不可变对象的赋值
62 
3.1.2 可变对象与别名 
一个变量赋值给另一个变量时,两个变量指向同一个对象,称为别名 (alias)。例如, 
图 3.2 中的两个变量 x 和 y 同时指向数据 3。 
再看以下赋值语句序列: 
>>> x = [1, 2, 3] 
>>> y = x 
>>> x[0] = 0 
>>> y 
[0, 2, 3] 
>>> x 
[0, 2, 3] 
第二个赋值语句使得 x 和 y 同时指向可变列表对象 [1,2,3]。在这种情况下,赋值语句 
x[0]= 0 修改了该对象的局部,所以,x 和 y 均指向修改后的对象。图 3.5(a) 显示第二 
个赋值语句y=x 执行之后的变量状态,图 3.5(b) 显示第三个赋值语句 x[0]=0 执行之 
后的变量状态。 
图 3.5 通过一个变量可以修改多个变量共同指向的列表 
需要注意的是,如果这种别名现象并不是我们想要的,那么应该使用列表的副本, 
使得修改列表的副本不会改变原有的列表。这种别名现象,特别是所指的对象是列表这 
样的可变对象时,有可能导致难以发现的错误(参见 5.1.3 节)。 
3.1.3 复合赋值 
形如 x = x+e 的赋值语句是一种常见的形式,它在变量 x 当前值基础上加上表达 
式 e 的值。对于这一类赋值语句,Python 支持简化的复合赋值(compound assignment), 
或称增强赋值(augmented assignment),写为 x += e。例如: 
>>> x = 0 
>>> x += 1 
>>> print(x) 
1 
赋值 x += 1 称为复合加法赋值,+= 称为复合加法运算符。类似地,对于其他的二元 
运算也可以使用相应的复合赋值,见表 3.1。
63 
表 3.1 复合赋值运算 
复合赋值运算符 名称 例 等效的赋值语句 
+= 复合加法赋值 i += 1 i = i + 1 
-= 复合减法赋值 i -= 1 i = i - 1 
*= 复合乘法赋值 i *= 2 i = i*2 
/= 复合浮点除法赋值 i /= 2 i = i / 2 
//= 复合整数除法赋值 i //= 3 i = i // 3 
%= 复合求模赋值 i %= 3 i = i % 3 
**= 复合幂赋值 i **= 2 i = i ** 2 
3.1.4 并行赋值 
Python 支持同时给多个变量赋值,即并行赋值 (simultaneous assignment)。例如 
>>> x, y = 1, 2 
>>> print(x) 
1
>>> print(y) 
2
>>> x, y = x + 1, x + y 
>>> print(x) 
2
>>> print(y) 
3 
并行赋值同时计算赋值号右边表达式的值,并从左到右将左边变量分别绑定对应表 
达式的值。 
并行赋值还可以用于交换两个变量的值。例如: 
>>> x, y = 1, 2 
>>> y, x = x, y 
>>> print(x,y) 
2 1 
3.1.5 输入和输出语句 
输入、输出和赋值是几个最简单的语句。输入语句 input() 用于接收用户在键盘 
输入的信息,其语法为 
input([prompt]) 
语法中的方括号 [] 表示其中的实参是可选的,即 input() 可以不带参数,也可以带参数。 
如果带参数,该参数是一个字符串,用于提示(prompt)用户输入。在执行 input() 
时,系统等待用户从键盘输入,直至用户按回车键,然后函数将用户输入的字符串返回, 
即函数 input() 的返回值是用户输入的字符串(不包括回车符)。例如: 
>>> name = input('What is your name:') 
What is your name: 高兴
64 
>>> name 
' 高兴' 
>>> age = input('How old are you:') 
How old are you:20 
>>> age 
'20'
注意,age 是一个字符串。但是,这里希望 age 的类型为 int,所以,通常在 input() 
外嵌套转换函数 int(): 
>>> age = int(input('How old are you:')) 
How old are you:20 
>>> age 
20 
输出语句 print() 用于将信息显示到屏幕上。 
输出语句 print() 的语法为 
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) 
它表示 print() 可以有多个打印参数 (*object 表示可以提供多个实参),后面的 4 个 
实参可以省略。如果省略,则将其中的输出参数逐个输出到标准输出文件(即屏幕, 
file=sys.stdout),两个单引号中间用空格分离 (sep=' '),最后换行(end='\n')。例 
如,用一个 print() 打印多个参数信息: 
>>> name = ' 高兴' 
>>> print('My name is', name, "and I'm", 20) 
My name is 高兴 and I'm 20 
也可以改变分隔符。例如: 
>>> name = ' 高兴' 
>>> print('My name is',name, "and I'm", 20,sep=' : ') 
My name is : 高兴 : and I'm : 20 
可以用多个 print() 语句打印参数信息。例如: 
>>> name = ' 高兴' 
>>> print('My name is'); print(name) 
My name is 
高兴
其中语句后的分号表示一个语句结束,这里用于表示连续执行两个语句。 
可以看到,两个 print() 语句分别打印在两行。如果希望将两个 print() 的信息显示 
在同一行,可以改变命名参数 end 的值。例如:
65 
>>> name = ' 高兴' 
>>> print('My name is',end=' '); print(name) 
My name is 高兴 
【注意】 Python 中的许多函数和方法都可以带不同个数的参数,即同一个名有不 
同用法,如这里的 input() 和 print()、第 2 章的函数 range()、字典上的查找方法 get() 
和删除方法 pop() 等。在程序设计中,这种用同一个名实现不同用法的方法称为重载 
(overloading)。 
3.1.6 表达式语句 
表达式语句 (expression statement) 由一个或者多个表达式构成,表达式之间用逗 
号分隔。例如,小海龟作图的命令: 
turtle.penup(), turtle.forward(100) 
表达式语句中,每个表达式通常是一个方法或者函数的调用,其目的是完成某个操 
作,而不是计算一个值(如 math.sqrt() 只是计算一个值)。主要任务是完成某种操作而 
不是计算一个值的函数也称为过程 (procedure)。表达式语句通常用于过程调用。 
3.2 分支结构 
分支结构用于控制在不同的条件下执行不同的语句。分支结构包括单分支 if、双分 
支 if-else 和多分支 if-elif-else 等条件语句。 
3.2.1 if 语句 
如果只有在某种条件 be 满足时才执行 S1,则使用 if 条件语句。图 3.6 给出带上 
下文的 if 语句的一般形式和程序框图(flowchart,也称程序运行流程图,简称流程图), 
即条件语句前后分别添加了语句 S0 和 S2。条件语句中 be 是一个布尔表达式,S0、S1 
和 S2 是一个语句或者多个语句构成的语句块。只有在表达式 be 的值计算为 True 时, 
S1 才会执行。S1 由多个语句构成时,要缩进左对齐。 
图 3.6 带上下文的 if 语句的一般形式和程序框图
66 
例如,设计一个程序,输入一个人的体重和身高,然后输出其 BMI。如果 BMI 小 
于 25,则输出“体重正常”字样,见程序 3.1。 
程序 3.1 计算 BMI 
weight = float(input('Input your weight (kg):')) 
height = float(input('Input your height(m):')) 
bmi = weight / height..2 
print('Your BMI is',round(bmi,2)) 
if bmi < 25: 
print('体重正常') 
尝试输入不同的体重和身高,查看其运行结果。 
【注意】 Python 解释器默认脚本使用编码 UTF-8 存储。在存储脚本时应选择编码 
UTF-8,以便解释器正确识别汉字。否则,对于包含汉字的脚本,Python 解释器可能报 
错,如“SyntaxError: Non-UTF-8 code starting with ... , but no encoding declared”。 
一种解决方法是重新用 UTF-8 编码存储文件,另一种解决方法是在脚本第一行用注释 
说明脚本编码,如 #coding=gbk。 
3.2.2 if-else 语句 
在计算并输出 BMI 的程序中,如果 bmi 变量的值小于 25,则输出“体重正常”, 
否则输出“有点超重哦:-)”,见程序 3.2。 
程序 3.2 计算 BMI 
weight = float(input('Input your weight(kg):')) 
height = float(input('Input your height(m):')) 
bmi = weight / height..2 
print('Your BMI is',round(bmi,2)) 
if bmi < 25: 
print('体重正常') 
else: 
print('有点超重哦:-)') 
图 3.7 给出带上下文的 if-else 语句一般形式和程序框图。 
3.2.3 if-elif-else 语句 
带上下文的多分支条件语句一般形式和程序框图如图 3.8 所示。 
例如,在计算并输出 BMI 的程序中,如果 bmi 变量的值小于 25,则输出“体重正 
常”;如果 bmi 变量的值介于 25 和 30 之间,则输出“有点超重哦:-)”;如果 bmi 变量 
的值大于 30,则输出“严重超重哦:-)”:
67 
图 3.7 带上下文的 if-else 语句的一般形式和程序框图 
图 3.8 带上下文的 if-elif-else 语句的一般形式和程序框图 
weight = float(input('Input your weight(kg):')) 
height = float(input('Input your height(m):')) 
bmi = weight / height**2 
print('Your BMI is',round(bmi,2)) 
if bmi < 25: 
print('体重正常') 
elif bmi < 30: 
print('有点超重哦:-)') 
else: 
print('严重超重哦:-)') 
例 3.1 编写模拟买彩票的程序。 
(1)随机生成一个两位数,可用 random 模块的 randint(10,99) 生成。
68 
(2)提示用户输入一个两位数的猜测值。 
(3)如果用户的猜测完全正确,则打印“您赢了 10 万元”;如果用户十位数猜对了, 
或者个位数猜对了,则打印“您赢了 100 元”;如果两位数都猜错了,则打印“您没有 
对上任何数”。 
(4)打印随机数。 
这里可以用 random.randint(10,99) 随机生成 10~99 的整数。另外,要取得一个两 
位整数的个位数和十位数,可以分别用 10 取模和做整数除法得到,见程序 3.3。 
程序 3.3 模拟买彩票 
import random 
answer = random.randint(10,99) 
guess = int(input('Input some int (10.99):')) 
answer0 = answer % 10 # 随机数的个位 
answer1 = answer // 10 # 随机数的十位 
if guess == answer: 
print('您赢了 10 万元') 
elif (guess % 10 == answer0) or (guess // 10== answer1): 
print('您赢了 100 元') 
else: 
print('您没有对上任何数') 
print('秘密数是',answer) 
3.3 循环结构 
循环语句用于表达某些语句的反复执行。一般程序设计语言均提供两种表示循环的 
语句:for 循环和 while 循环。当重复的次数确定时,通常使用 for 循环语句;当重复的 
条件确定时,通常使用 while 循环语句。 
3.3.1 for 循环语句 
for 循环语句用于表达重复执行某个语句(块)一定的次数。for 循环伪代码与 
Python 代码对照见表 3.2。 
表 3.2 for 循环伪代码和 Python 代码对照 
伪代码 Python 代码 说明 
for i ← 0 to n . 1 for i in range(n): 注意 Python 代码中的冒号; 
S S 循环体 S 要缩进并左对齐 
例如,打印下面的图形: 
##### 
#####
69 
##### 
##### 
完成这个任务的算法是 
重复执行下列语句4次: 
打印 "#####" 
或者(n=4) 
for i = 0 to n-1: 
打印 "#####" 
所以,Python 程序可以写成 
for i in range(4): # i分别取0、1、2、3这4个值 
print("#####") 
再如,打印 1~10 各数的平方: 
for i in range(1,11): 
print(i, '*', i, '=', i ** 2) 
输出结果如下: 
1 * 1 = 1 
2 * 2 = 4 
3 * 3 = 9 
4 * 4 = 16 
5 * 5 = 25 
6 * 6 = 36 
7 * 7 = 49 
8 * 8 = 64 
9 * 9 = 81 
10 * 10 = 100 
for 语句的一般形式和程序框图如图 3.9 所示。 
图 3.9 for 语句的一般形式和程序框图
70 
例 3.2 设计一段求第 n 个斐波那契数的程序。输入是 n,输出斐波那契数列 
f0 = 0, f1 = 1, f2 = 1, f3 = 2, f4 = 3, · · · 中的 fn。 
【方法】 将以上迭代计算方法写成算法。 
计算的方法是:每次将现有的两个数相加,得到下一个数:如果用两个变量 f1 和 
f2 分别表示当前计算出的两个斐波那契数,那么下一个数是 f3 = f1 + f2。为了重复这 
个关键步骤,需要每次都用 f1 和 f2 分别表示当前计算出的两个斐波那契数,因此,在 
完成计算 f3 = f1 +f2 后,需要用 f1 存储 f2 的值,f2 存储 f3 的值,并重复这个过程, 
直至求得所需的值。 
【算法】 由此得到算法 3.1。 
算法 3.1 fib(n) 
输入: n . 2 是一个整数 
输出: 输出第 n 个斐波那契数 
f1 ← 0 
f2 ← 1 
for i ← 1 to n . 1 do 
f3 ← f1 + f2 
f1 ← f2 
f2 ← f3 
输出 f3 
【代码】 对于这种形式的伪代码,在学习 Python 函数之后,很容易将其转换为 
Python 函数。在使用自定义函数之前,我们只用 Python 函数表达算法,并在算法的 
第一个语句之前设置输入参数。例如,通过赋值语句或者输入语句 input() 设置输入参 
数。由此得到程序 3.4。 
程序 3.4 求第 n 个斐波那契数 
n = int(input("输入整数:")) 
f1 = 0 
f2 = 1 
for i in range(1,n): 
f3 = f1+f2 
f1 = f2 
f2 = f3 
print("第"+ str(n) +"个斐波那契数 :", f3) 
【注意】 程序设计中经常用迭代 (iteration) 这个术语。类似于数学上的迭代公式, 
它表示重复某种操作有限次,直至得到所需的数据。迭代也泛指循环。使用迭代设计算 
法时,最关键的是说明重复的操作以及重复的次数或者重复的条件。 
3.3.2 while 循环语句 
如果需要在一定的条件下重复执行一个或者一组语句,可以使用 while 循环语句。
71 
while 循环伪代码与 Python 代码对照见表 3.3。 
表 3.3 while 循环伪代码和 Python 代码对照 
伪代码 Python 代码 说明 
while condition while condition: 注意 Python 代码中的冒号; 
S S 循环体 S 要缩进并左对齐 
while 循环语句的一般形式和程序框图如图 3.10 所示。 
图 3.10 while 循环语句的一般形式和程序框图 
例如,输出 1 至 10 的平方根; 
import math 
i = 1 
while i <= 10: 
print('squre root of ', i, 'is', round(math.sqrt(i), 2)) 
i = i + 1 
输出结果如下: 
squre root of 1 is 1.0 
squre root of 2 is 1.41 
squre root of 3 is 1.73 
squre root of 4 is 2.0 
squre root of 5 is 2.24 
squre root of 6 is 2.45 
squre root of 7 is 2.65 
squre root of 8 is 2.83 
squre root of 9 is 3.0 
squre root of 10 is 3.16 
需要特别注意的是,while 循环中应该保证循环变量的值不断变化,在有限步后使 
得循环条件不成立,因此终止循环语句。例如,上例中的循环变量 i,如果循环体中没 
有语句 i = i + 1,则每次循环后 i 的值 1 保持不变,因此出现无限循环。
72 
例 3.3 猜数游戏。 
问题陈述如下: 
(1)程序秘密设定一个 1~50 的数 secret。 
(2)程序提示用户输入一个猜测值 answer。 
(3)如果 answer 等于 secret, 则程序结束,输出“猜中了”字样;否则提示用户猜 
测的值是大于 secret 还是小于 secret,让用户继续猜,直至猜中。 
【方法】 将以上陈述进一步细化: 
(1)程序秘密设定一个 1~50 的数 secret,可用 randint(1,50) 随机生成。 
(2)程序提示用户输入一个猜测值,并将该输入数值记作 answer。 
(3)当 answer 不等于 secret 时,重复下列步骤: 
.1 提示用户猜测的值是大于 secret 还是小于 secret。 
.2 让用户继续猜,并仍用 answer 记录用户输入的猜测值。 
(4)以上循环结束时,answer 等于 secret,输出“猜中了”字样,程序结束。 
【算法】 至此,可以将以上方法写成伪代码形式的算法 3.2。 
算法 3.2 guessNumber() 
secret ← randint(1, 50) //生成一个 1~50 的秘密数 
answer ← 读取用户的猜测值 
while answer .= secret do 
if answer > secret then 
输出提示信息"猜的大了" 
else 
输出提示信息"猜的小了" 
answer ← 用户的猜测值 
输出信息 "猜中了" 
注意,这里重复猜测的次数是不确定的,但是重复的条件是确定的,即当且仅当猜 
测值等于秘密值的时候才结束猜测,因此使用 while 循环。 
【代码】 算法 3.2 的实现见程序 3.5。 
程序 3.5 猜数游戏 
import random 
secret = random.randint(1,50) 
answer = int(input("输入一个 1~50 的整数:")) 
while answer != secret: 
if answer > secret: 
print("您这次的猜测大了") 
else: 
print("您这次的猜测小了") 
answer = int(input("请再输入一个 1~50 的整数:")) 
print("您猜中了!是",secret)
73 
例 3.4 用猜数的方法求一个数的平方根,如 √2。 
【方法】 首先,已知 1 < √2 < 3, 或者说 √2 ∈ (a, b), 其中 a = 1, b = 3。第一次猜 
区间 (a, b) 的中点 c = (a+b)/2。如果 c2 > 2, 则说明 2 的平方根介于 a 和 c 之间,因此 
到区间 (a, c) 上接着猜;如果 c2 < 2, 则到区间 (c, b) 上接着猜。重复这个过程,直至包含 
√2 的区间足够小,或者足够精确时,则可取最后一个包含 √2 的区间中点作为近似值。 
将以上求 √2 近似值的二分猜测法进一步细化如下: 
(1)设定初始包含 √2 的区间 (a, b) 为 (1, 3)。 
(2)设定一个精度:e = 0.001。 
(3)重复下列步骤,直至 |b . a| < e: 
.1 取区间 (a, b) 的中点 c = (a + b)/2。 
.2 如果 c2 > 2, 则到区间 (a, c) 上接着猜, 即 (a, b) = (a, c)。 
.3 如果 c2 < 2, 则到区间 (c, b) 上接着猜, 即 (a, b) = (c, b)。 
(4)取区间 (a, b) 的中点 c = (a + b)/2 作为 √2 的近似值。 
表达循环的关键在于每次循环都用 (a, b) 表达 2 的平方根所在的区间。 
【算法】 现在可以将以上方法写成伪代码形式的算法(见算法 3.3)。同样,因为 
循环的次数不确定,但是循环条件确定,因此使用 while 循环。 
算法 3.3 my_sqrt() 
输出: 计算 2 的近似平方根 
(a, b) ← (1, 3) 
e ← 0.001 
while |b . a| . e do 
c ← (a + b)/2 
if c2 > 2 then 
(a, b) ← (a, c) 
else 
(a, b) ← (c, b) 
输出近似值 (a + b)/2 
【代码】 容易将算法 3.3 转换为程序 3.6。 
程序 3.6 计算 2 的平方根 
"""Find square root of 2 with precision e""" 
e = 0.001 # 精度 
a, b = 1.0, 3.0 # 初始区间 
while abs(b.a) >= e: 
c = (a + b) / 2 
if c..2 > 2: 
a, b = a, c 
else:
74 
程序 3.6 (续表) 
a, b = c, b 
c = (a + b) / 2 
print("2 的平方根近似值:", c) 
# 运行结果为"2 的平方根近似值:1.41455078125" 
这里用到了并行赋值,即多个赋值语句同时进行:计算赋值语句右边的表达式,然 
后将其同时赋值给左边的变量。 
求平方根收敛最快的方法是牛顿-拉弗森(Newton-Raphson)公式,见习题 3.9。 
3.3.3 循环的控制:break 和 continue 
在循环体中,可能需要依据某个条件调整循环执行的逻辑。例如,中断循环,或者 
结束本次循环,进入下一次循环。break 语句将中断包含该语句的循环,转去执行循环 
语句后的语句。例如: 
for i in range(1, 10): 
if i ** 2 <= 5: 
print(i ** 2) 
else: 
break 
print('break goes to here') 
print('i = ', i) 
在上面代码中,for 循环语句后的第一个语句是与 for 对齐的第一个 print(),因此 
程序输出结果如下: 
1
4
break goes to here 
i = 3 
语句 continue 将结束本次循环,并进入下一次循环,即跳过本次循环的剩余语句, 
进入下一次循环。例如: 
for i in range(1, 10): 
if i % 2 == 0: 
print(i) 
else: 
continue 
print('current i =', i) 
在以上代码中,当 i 取奇数时 if 条件不成立,因此跳过条件语句后的 print 语句, 
进入下一次循环,输出结果如下:
75 
2
current i = 2 
4
current i = 4 
6
current i = 6 
8
current i = 8 
有的算法可能完成循环后终止,也可能在循环过程中终止,即算法有两个出口,例 
如算法 1.2。对于这种情况,可以使用 Python 的带 else 的 while 循环: 
while condition: 
S1 
else: 
S2 
其中循环条件 condition 成立时执行语句 S1,不成立时执行 S2。如果语句块 S1 包含 
break 语句,则执行 break 后终止循环,不再执行语句 S2。 
循环可能有两种终止方式(在循环体中终止和在循环条件不成立后终止),中间可 
能终止的 while 循环伪代码和 Python 代码对照见表 3.4。 
表 3.4 中间可能终止的 while 循环伪代码和 Python 代码对照表 
伪代码 Python 代码 说明 
while condition1 while condition1: 注意 Python 代码中的冒号; 
S1 S1 语句块要缩进并左对齐 
if conditon2 if condition2: 
S2 S2 
STOP break 
S3 S3 
S4 else:
S4 
例 3.5 判断任意一个正整数是否素数。 
【方法】 判断一个正整数 n 是否素数的基本方法:依次检查 2, 3, · · · , n.1 是否为 
n 的因子,如果其中一个数是因子,则输出“合数”并终止,否则输出“素数”并终止。 
【算法】 循环选择 for 和 while 均可。本例的算法如算法 3.4 所示。 
【代码】 因为算法可能在检查到因子时终止,而且不执行 while 循环后的语句,因 
此使用了带 else 的循环。将算法转换为带 else 的循环的 Python 代码见程序 3.7。 
程序 3.7 判断一个正整数是否素数的代码 
n = int(input('input some int:')) 
factor = 2
76 
程序 3.7 (续表) 
while (factor < n): 
if (n % factor == 0): 
print(n, 'is not a prime') 
break 
else:
factor += 1 
else: 
print(n, 'is a prime') 
算法 3.4 isPrime(n) 
输入: n 是正整数,n . 2 
输出: 如果 n 是素数,则输出“素数”,否则输出“合数” 
factor ← 2 
while factor . n . 1 do 
if n%factor = 0 then 
输出"合数" 
算法终止 
else 
factor ← factor + 1 
输出 "素数" 
对于以上判断素数的例子,另一种方法是设置一个布尔型标记变量 is_prime,根 
据该变量的值决定是否结束循环以及循环结束后执行的语句。例如,程序 3.8 中,将变 
量 is_prime 初始化为 True。在检测 n 是否有因子的循环中,一旦发现有因子,则将 
is_prime 置为 False,并终止循环(break)。在循环之后,根据 is_prime 的值打印 
相应信息。 
程序 3.8 使用一个布尔标记判断一个正整数是否素数的代码 
n = int(input('input some int:')) 
factor = 2 
is_prime = True 
while (factor < n): 
if (n % factor == 0): 
is_prime = False 
break 
else:
factor += 1 
if is_prime: 
print(n, 'is a prime') 
else: 
print(n, 'is not a prime')
77 
3.3.4 循环嵌套 
循环可以嵌套,即循环体中的语句也可以是一个 for 循环或者 while 循环。 
例如,打印如图 3.11 所示的九九乘法表,可以使用如下代码: 
for i in range(1,10): 
for j in range(1,10): 
print(format(i * j, '4d'), end = ' ') 
print() 
其中外循环的循环体包含两个语句,第一个语句也是一个 for 循环,第二个语句是一个 
简单的 print 语句。外循环控制行,内循环打印各行信息。 
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
图 3.11 九九乘法表 
为了将每 9 个乘积显示在同一行,并各列对齐,需要说明各个乘积占用的宽度。这 
里使用了格式(formatting)函数 format(value, format_spec)。其中,第一个参数 
value 表示打印的值;第二个参数 format_spec 是字符串,表示打印格式,包括对齐方 
式、占用宽度、精度和类型等。这里,format(i * j, '>4d') 表示乘积 i * j 将占 4 
位,右对齐(用 > 表示),d 表示第一参数的类型是整数。下面给出打印数值和字符串 
的典型例子: 
. 打印整数 123456(用 d 表示整数类型),左对齐(用 < 表示),占用 10 位,空 
白位置用#填充: 
>>> print(format(123456,'#<10d')) 
123456#### 
. 打印浮点数 123.456(用 f 表示浮点数类型),右对齐(用 > 表示),占用 10 位, 
其中小数点后保留 2 位 (用.2 表示): 
>>> print(format(123.456,'>10.2f')) 
123.46 
打印数值右对齐时,可以省去对齐符号 >。 
. 打印字符串'Python Programming'(用 s 表示字符串类型),居中对齐(用^表 
示),占用 30 位:
78 
>>> print(format('Python Programming', '^30s')) 
Python Programming 
此外,打印语句中的 end 参数表示该打印语句末尾不换行,而是用一个空格结尾。 
这样便可以用内循环将九个乘积输出在同一行,外循环的第二个语句 print() 达到换 
行目的。 
如果在九九乘法表外围打印一些装饰,则可以产生更完整、美观的九九乘法表。例如: 
print(format("九九乘法表\n", '^40s')) # 标题字符串居中 
print("i*j | ", end = '') 
for j in range(1, 10): 
print(" ", j, end = ' ') # 打印表头 
print() # 换行 
print("-"*50) 
# 显示乘法表 
for i in range(1, 10): 
print(format(i, '2d'), " |", end = ' ') 
# 内循环将9个乘积显示在同一行 
for j in range(1, 10): 
print(format(i * j, '4d'), end = ' ') 
print() # 换行 
以上程序打印数值时采用右对齐格式,因此省去了右对齐符号 >。程序输出见 
图 3.12。 
九九乘法表 
i*j | 1 2 3 4 5 6 7 8 9 
-------------------------------------------------- 
1 | 1 2 3 4 5 6 7 8 9 
2 | 2 4 6 8 10 12 14 16 18 
3 | 3 6 9 12 15 18 21 24 27 
4 | 4 8 12 16 20 24 28 32 36 
5 | 5 10 15 20 25 30 35 40 45 
6 | 6 12 18 24 30 36 42 48 54 
7 | 7 14 21 28 35 42 49 56 63 
8 | 8 16 24 32 40 48 56 64 72 
9 | 9 18 27 36 45 54 63 72 81 
图 3.12 加上行列号的九九乘法表 
习题 
3.1 设计一个计算一元二次方程 ax2 + bx + c = 0 的根的程序。输入分别是 3 个实数 
a、b 和 c,根据判定式打印两个实根,或者打印“不存在实根”。
79 
3.2 设计程序,用户输入一个课程成绩(score),程序根据表 3.5 判断并输出等级。 
表 3.5 成绩范围与等级 
成绩范围 等级 
score .90 A 
80. score < 90 B 
70 . score <80 C 
60 . score < 70 D 
score < 60 F 
3.3 参照《中华人民共和国个人所得税法》最新个人所得税率,设计一个计算个人所 
得税的程序。 
3.4 编写程序打印每边由 n 个 * 构成的菱形图案。要求第一个语句给变量 n 赋一个初 
值,例如: 
n = 10 
接下来的语句将直接使用 n,而不是使用 10,这样只需要修改此赋值语句右边的常数 
即可打印每边由任意 n 个 * 构成的菱形图案。 
3.5 分别用 for 和 while 循环编写一段程序,判断一个正整数是否素数。要求:提示用 
户输入一个正整数,然后打印该数是否素数的信息。 
3.6 编写程序,对于任意给定的正整数 n,在 turtle 中画出正 n 边形。类似于习题 3.4, 
要求第一个语句给 n 赋一个具体的值,如 n = 5,接下来的语句将使用 n 而不是具体 
的值(如 5)表达角度,这样只需修改第一个赋值语句右边的数值,即可画出指定的正 
n 边形。 
提示:正 n 边形内角和为 180(n . 2),由此可计算每个内角及外角度数。 
3.7 设计一个模拟猜拳(石头剪刀布)的游戏模拟程序。设想有两个玩家,每个玩家 
(随机)出一个手势,由程序判断这一轮谁赢。然后让玩家继续出手势,直至分出胜负, 
例如三局两胜。 
例如,程序的输出可能是这样的: 
玩家 A 出“剪刀” 
玩家 B 出“布” 
玩家 A 胜,1-0 
玩家 A 出“剪刀” 
玩家 B 出“布” 
玩家 A 胜,2-0 
玩家 A 出“剪刀” 
玩家 B 出“剪刀” 
平手,2-0 
玩家 A 出“剪刀”