第3章 Python程序控制结构

【考核目标】

了解:算法的基本概念,简单算法流程图的绘制方法

理解:break和continue的使用方法,推导式的使用方法

掌握:程序的选择结构和训话脑结构及其语法格式

应用:能够运用if语句实现选择结构程序设计,能够运用for语句和while语句实现循环结构程序设计

3.1 程序设计基础

3.1.1 程序和程序设计

程序是计算机指令的某种集合,控制计算机的工作流程,完成一定过的逻辑功能,以实现某种任务。程序设计是给出解决特定问题程序的过程,是软件构造活动中的重要组成部分

程序设计的基本步骤

  1. 对用户需求进行分析
  2. 设计算法,并画出相应算法流程图
  3. 选择编程语言实现所设计的算法
  4. 根据程序结果,调试程序代码
  5. 根据用户需要升级维护程序

著名的计算机科学家、图灵奖获得者尼古拉斯·沃斯(Niklaus With)曾经提出一个经典公式:程序 = 数据结构 + 算法。其中数据结构(data structure)是数据的描述和组织形式,算法(algorithm)是指对解决某问题的流程或步骤进行描述

3.1.2 算法及其描述

算法是对特定问题求解步骤的一种描述,是独立存在的一种解决问题的方法和思想。同一个问题,可以有不同的解题方法和步骤,也就有不同的算法

例如求 ∫ a b f ( x ) d x \int_{a}^{b}{f(x)}dx abf(x)dx可采用矩形法、梯形法、辛普森法(即抛物线法)等。为了有效地解题,不仅需要保证算法正确,还要考虑算法的质量,从而选择较好的算法,或进行算法的优化

算法具有以下特点

  1. 仅有有限的操作步骤,即“有穷性”(无死循环)
  2. 算法的每一个步骤应当是确定的,即无“二义性”
  3. 有适当的输入,即有确定的条件
  4. 有输出结果,没有输出的算法是无意义的
  5. 算法中的每一个步骤都应当有效执行(无死语句)

算法的表示可以有多种形式,常用的有自然语言、传统流程图、伪代码、N-S流程图等

1. 自然语言

自然语言就是人们日常使用的语言,如汉语、英语和其他语言等。用自然语言描述算法通俗易懂,但由于自然语言表示的含义往往不太严格,需要根据上下文才能判断其准确含义,所以描述文字冗长,容易出现“歧义性”。此外,用自然语言描述包含分支结构和循环结构的算法不太方便。因此,除了很简单的问题以外,一般不用这种描述方法

2. 传统流程图

流程图是用一系列的图像、流程线和文字描述算法的基本操作和控制流程,又称算法流程图或程序流程图。流程图的基本元素包括起止框、判断框、处理框、输入输出框、注释框、流向线和连接点等,如下图所示

其中:

  • “起止框”表示程序的开始和结束
  • “判断框”表示对给定条件进行判断,根据给定条件是否成立决定执行其后的操作,包含一个入口、两个出口
  • “处理框”表示一组处理的过程
  • “流向线”以带箭头直线或曲线形式指示程序的路径
  • “输入输出框”表示数据的输入或结果的输出
  • “连接点”将多个流程图连接到一起,常用于将一个较大流程图分割为若干部分

**【例3-1】**求函数f(x)在区间[a, b]上的积分 ∫ a b f ( x ) d x \int_{a}^{b}{f(x)}dx abf(x)dx。流程图如下所示

3. 伪代码

伪代码(pseudocode)是一种非正式的,类似于英语结构的,用于描述模块结构图的语言,介于自然语言与编程语言之间。使用伪代码的目的是使被描述的算法可以容易地以任何一种编程语言(Python,C,Java等)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。例3-1伪代码表示如下:

开始(begin)
输入(Input) a, b, n
(b - a) / n --> h
0 --> s
1 --> i
当(while) i <= n 执行(do)
s + h * f(a + (i - 1) * h) --> s
i + 1 --> i
循环到此结束(end do)
输出(print) a, b, n, s
算法结束(end)

4. N-S流程图(盒图)

盒图最早由I.Nassi和B.Shneiderman在1973年发表的题为“结构化程序设计的流程图技术”一文中提出,因此也称为N-S图。N-S图含有三种基本控制结构来构造程序逻辑,复合结构化程序设计原则

3.1.3 IPO程序编写方法

输入(input)数据:输入是一个程序的开始。程序要处理的数据有多种来源,形成了多种输入方式,包括:文件输入、网络输入、控制台输入、交互界面输入、随机数据输入、内部参数输入等

处理(process)数据:处理是程序对输入数据进行计算产生输出结果的过程。计算问题的处理方法统称为“算法”,它是程序最重要的组成部分。可以说,算法是一个程序的灵魂

输出(output)数据:输出是程序展示运算结果的方式。程序的输出方式包括:控制台输出、图形输出、文件输出、网络输出、操作系统内部变量输出等

IPO描述主要用于区分程序的输入输出关系,重点在于结构划分,算法主要采用自然语言描述。流程图侧重于描述算法的具体流程关系,流程图的结构化关系相比自然语言描述更进一步,有助于阐述算法的具体操作过程。Python代码描述是最终的程序产出,最为细致。对于一个计算问题,可以用IPO描述、流程图描述或者直接以Python代码方式描述

**【例3-2】**输入一个实数,求该数绝对值

(1) 问题IPO描述

输入:实数R

处理:|R| = { R R ≥ 0 − R R < 0 \begin{cases}R & R \ge 0\\-R & R < 0\end{cases} {RRR0R<0

输出:输出|R|

(2) 流程图描述如下图所示

(3) Python代码描述

R = eval(input("输入实数:"))
if (R < 0):
    R *= -1
print("绝对值", R)

3.1.4 程序的基本结构

所有计算机程序都是由顺序结构、选择结构、循环结构这三种基本结构组成。1966年,计算机科学家Bohm和Jaeopini证明了任何简单或复杂的算法都可以由这三种基本结构组合而成

三种基本结构的共同特点

  1. 只有一个入口
  2. 只有一个出口
  3. 结构内的每一部分都有机会被执行到
  4. 结构内不存在”死循环“(无终止的循环)

3.2 顺序结构

顺序结构是程序按照线性顺序依次执行的一种运行方式,如下图所示,其中语句块1和语句块2表示一个或一组顺序执行的语句。顺序结构是最简单、最基本的一种结构

**【例3-3】**输入半径,计算圆面积和周长

思路分析:

圆的半径为R,则圆的面积S=Π×R2,周长L=2Π×R,程序运行时首先输入R,然后输出S、C的计算结果

程序代码:

R = input("请输入圆的半径:")
R = eval(R)
S = 3.1415 * R * R
L = 2 * 3.1415 * R
print("圆的面积和周长:", S, L)

运行结果:

请输入圆的半径:3
圆的面积和周长: 28.2735 18.849

**【例3-4】**输入三角形三边长并计算面积。利用 s = h ( h − a ) ( h − b ) ( h − c ) s= \sqrt{h(h-a)(h-b)(h-c)} s=h(ha)(hb)(hc) ,其中 h = a + b + c 2 h=\frac{a+b+c}{2} h=2a+b+c

思路分析:

分别通过input()函数输入三角形的三个边的长度a,b,c,然后根据海伦公式计算任意三角形面积S并输出

程序代码:

import math
a = float(input("请输入三角形边长a:"))
b = float(input("请输入三角形边长b:"))
c = float(input("请输入三角形边长c:"))
h = (a + b + c) / 2
s = math.sqrt(h * (h - a) * (h - b) * (h - c))
print("三角形三边分别为:a={},b={},c={},面积={:.3}".format(a, b, c, s))

运行结果:

请输入三角形边长a:2
请输入三角形边长b:3
请输入三角形边长c:4
三角形三边分别为:a=2.0,b=3.0,c=4.0,面积=2.9

**【例3-5】**从键盘输入一个3位整数,计算并输出这个3位整数各位数字之和

思路分析:

给定一个3位整数n:

(1) 个位上数字:n除10取余

(2) 十位上数字:n除10取整,再除10取余

(3) 百位上数字:n除100取整

程序代码:

n = int(input("请输入一个3位整数:"))
ge = n % 10
shi = n // 10 % 10
bai = n // 100
sum = ge + shi + bai
print("整数各位数字之和:", sum)

运行结果:

请输入一个3位整数:123
整数各位数字之和: 6

3.3 程序的分支结构

分支结构是程序根据条件判断结果选择不同执行路径的一种运行方式,包括单分支结构和双分支结构,以及由双分支结构组合形成的多分支结构

3.3.1 单分支结构:if语句

Python中if语句的语法格式:

if <条件表达式>:
	语句块

其流程图如下所示。其中:

(1) if为保留字

(2) 条件表达式可以是关系表达式、逻辑表达式、算术表达式等任意合法的表达式,其最后评价布尔逻辑值为真(True)或假(False)。条件表达式的结果如果为False、0、空值None、空字符串(“”)、空元组(())、空列表([])、空字典({})或其他空迭代对象,则其布尔逻辑值为假(False),否则其布尔逻辑值为真(True)

(3) 冒号(:)是不可缺少的,表示后面是满足条件后要执行的语句块

(4) 语句块是由若干个(单个或多个)具有相同缩进量的语句组成,语句块要比if语句多缩进若干个字符,通常4个字符

单分支结构(if语句)执行过程:首先判断条件表达式的值是否为真(True),当条件表达式的值为真(True)或者其他等价值时,执行该语句块;否则不执行语句块

if语句中<条件表达式>部分可以使用任何能够产生True或False的语句;形成判断条件最常见的方式是采用关系操作符,Python语言共有6个关系操作符:<、<=、>、>=、==、!=

**【例3-6】**计算分段函数值 y = { c o s x + x 2 + 1 ( 其他 ) x x + x ( x ≥ 0 ) y=\left\{\begin{matrix} cosx+\sqrt{x^{2}+1}(其他) \\x\sqrt{x+\sqrt{x}} (x\ge0)\end{matrix}\right. y={cosx+x2+1 (其他)xx+x (x0)

程序代码:

from math import sqrt
x = eval(input("请输入x的值:"))
if x < 0:
    y = cos(x) + sqrt(x * x + 1)
if x >=0:
    y = x * sqrt(x + sqrt(x))
print("x={},y={:.3}".format(x, y))

运行结果:

请输入x的值:10
x=10,y=36.3

**【例3-7】**简化PM2.5空气质量提醒:0~35为优,36~75为良,75以上为污染。试根据输入的PM2.5数值,输出空气质量

思路分析:

输入:接收外部输入PM2.5的值

处理:

  • if PM2.5的值 >= 75 打印空气污染警告
  • if 35 <= PM2.5的值 < 75 打印空气污染警告
  • if PM2.5的值 < 35 打印空气质量优,建议户外运动

输出:打印空气质量提醒

程序代码:

PM = eval(input("请输入PM2.5的数值:"))
if PM >=0 and PM < 35:
    print("空气优质,快去户外运动!")
if PM >= 35 and PM < 75:
    print("空气良好,适合户外运动!")
if PM >= 75:
    print("空气污染,出行请小心!")

运行结果:

请输入PM2.5的数值:50
空气良好,适合户外运动!

3.3.2 双分支结构:if-else语句

Python中if-else语句用来形成双分支结构,语法格式:

if <条件表达式>:
	<语句块1>
else:
	<语句块2>

其流程图如下图所示。其中:

(1) if和else是保留字

(2) 语句块1和语句块2要比if和else多缩进若干字符

双分支结构(if-else语句)的执行过程:首先判断条件表达式的值,当条件表达式为真(True)时,执行if后面语句块1,否则执行else后面的语句块2

双分支语句用于区分<条件表达式>的两种可能——True或者False,分别形成路径

**【例3-8】**从键盘输入一个整数,判断其是否是偶数,若是,输出“偶数”,否则输出“奇数”

思路分析:

(1) 输入一个整数n

(2) 如果n % 2 = 0,则输出“偶数”;否则输出“奇数”

程序代码:

n = int(input("请输入一个整数n:"))
if n % 2 == 0:
    print("偶数")
else:
    print("奇数")

运行结果:

请输入一个整数n:4
偶数

双分支结构还有一种更简洁的表达方式,适合通过判断返回特定值,语法格式:

<语句块1> if <条件表达式> else <语句块2>

执行过程:当条件表达式为真(True)时,执行语句块1,否则执行语句块2

例如:

PM= eval(input("请输入PM2.5的数值:"))
print("空气{}污染!".format("存在" if PM >= 75 else "没有"))

3.3.3 多分支结构:if-elif-else语句

Python的if-elif-else多分支结构,语句格式:

if <条件表达式1>:
	<语句块1>
elif <条件表达式2>:
	<语句块2>
...
else:
	<语句块n>

其流程图如下所示。其中:

(1) if、elif、else是保留字,elif是else if的简写,表示带条件的else语句

(2) if语句块、elif语句块、else语句块要比if、elif和else多缩进若干个字符

多分支语句(if-elif-else)执行过程:首先判断if条件(条件表达式1),当条件表达式1为真(True)或其他等价值时,则执行if语句块1;否则判断elif条件(条件表达式2),当条件表达式2为真(True)或其他等价值时,则执行elif语句块2(否则依次判断下一个elif条件表达式,直到elif条件表达式为True或全部判断);若前面条件全部False,则执行else语句(语句块n)

多分支结构是二分支结构的扩展,这种形式通常用于设置同一个判断条件的多条执行路径。Python依据条件表达式的值,确定是否执行该条件下的语句块,结束后执行if-elif-else结构后面的语句。如果没有任何条件成立,则else下面的语句块被执行。另外,else子句是可选的

**【例3-9】**已知坐标点(x, y),判断其所在的象限

程序代码:

x = int(input("请输入x坐标:"))
y = int(input("请输入y坐标:"))
if (x == 0 and y == 0):
    print("位于原点")
elif (x == 0):
    print("位于y轴")
elif (y == 0):
    print("位于x轴")
elif (x > 0 and y > 0):
    print("位于第一象限")
elif (x < 0 and y > 0):
    print("位于第二象限")
elif (x < 0 and y < 0):
    print("位于第三象限")
else:
    print("位于第四象限")

运行结果:

请输入x坐标:0
请输入y坐标:0
位于原点

3.3.4 嵌套选择结构

嵌套选择结构是指选择结构(if语句、if-else语句或if-elif-else语句)中的语句块又包含一个或多个选择结构(if语句、if-else语句或if-elif-else语句)

if 条件表达式1:
	if 条件表达式2:
		语句块1
	else:
		语句块2
else:
	语句块3

**注意:**嵌套选择结构要注意缩进,if与之匹配的else需要缩进同样多的空格

**【例3-10】**输入一个整数X,根据下列分段函数计算并输出Y的值

Y = { 3 X ( X < = 50 ) 5 X ( 50 < X < = 100 ) 7 X ( X > 100 ) Y= \left\{\begin{matrix} 3X(X <= 50) \\ 5X(50 < X <= 100) \\ 7X(X > 100) \end{matrix}\right. Y= 3X(X<=50)5X(50<X<=100)7X(X>100)

程序代码:

x = int(input("x:"))
if x <= 50:
    y = 3 * x
else:
    if x <= 100:
        y = 5 * x
    else:
        y = 7 * x
print("y={}".format(y))

运行结果:

x:30
y=90

【育德悟道】

通过对选择结构经典案例分析讲解,我们可以从中得到一些人生哲理,当我们在面对多种抉择时一定要慎重,一旦做出抉择,我们要敢于承担后果,不要患得患失

3.4 程序的循环结构

程序的循环结构是程序能够根据所给判定条件(又称循环条件)是否满足,重复执行一条或多条语句。循环体是指被重复执行的一条或多条语句。Python循环结构使用for语句和while语句来实现,根据需要可以使用三种特殊语句:break语句、continue语句和else语句

Python中,根据循环体执行次数是否提前确定,循环语句可分为确定次数循环和非确定次数循环。确定次数循环是程序能提前确定循环体执行次数,适用于遍历或枚举可迭代对象中元素的场合,又称遍历循环,可采用for循环语句实现。非确定次数循环是程序不能提前确定循环体可能执行的次数,通过循环条件判断是否继续执行循环体,可采用while循环语句实现

3.4.1 for循环语句

确定次数循环指循环体对循环次数有明确的定义,这类循环在Python中称“遍历循环”,其循环次数采用for语句遍历结构中的元素个数

语法格式:

for <循环变量> in 可迭代对象:
	循环体

其流程图如下图所示。其中:

(1) for和in是保留字,提示后面语句是for遍历循环语句

(2) 循环变量是控制循环执行次数的变量,用于存放从可迭代对象中逐一遍历的元素。每次循环,可迭代对象中所遍历的元素放入循环变量,并执行一次循环体,直至遍历完所有元素后循环结束

(3)可迭代对象(iterable)是指能够实现iter()方法的对象,包括字符串、元组、列表、字典、文件、迭代器和生成器等

(4)冒号(:)是不可缺少的,表示循环变量满足时要执行的语句块

(5) 循环体是由单层或多层缩进语句组成

可迭代对象(iterable)是指能够实现iter()方法的对象。iter()方法返回迭代器(iterator)本身。Python中大部分对象都是可迭代的,如字符串、元组、列表、字典、文件、迭代器、生成器等

迭代器(iterator)是指能够实现iter()和next()方法的对象。迭代器调用next()方法时,会返回其下一个值。如果迭代器调用next()方法,但没有值返回,则产生StopIteration异常

生成器(generator):Python中一边循环,一边计算的机制叫作生成器。它包括两种类型:生成器函数和生成器表达式(将列表生成式的[]换成())。生成器函数是指包含yield语句的函数;生成器表达式是列表推导式的生成器版本,返回一个生成器对象。生成器是一种特殊的迭代器

可迭代对象遍历实例

(1)迭代(遍历)字符串

>>> str1 = "organge"
>>> for ch in str1:print(ch)

(2) 迭代元组

>>> numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> for number in numbers: print(number)

(3) 迭代列表

>>> words = ["I", "love", "python"]      
>>> for word in words: print(word)

(4) 迭代字典

>>> dict1 = {"a": 10, "b": 20, "c":30}
>>> for key in dict1: print(key, ":", dict1[key])

注意:

字典是无序序列,其元素的排列顺序是随机的

(5) 迭代range()对象

>>> for n in range(100): print(n, end = ", ")
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 
>>> for n in range(1, 100, 2): print(n, end = ", ")
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 

(6) 并行迭代

>>> keys = ["xh", "xm", "xb", "age"]      
>>> values = ["2021", "liu", "male", 18]
>>> for n in range(len(keys)): print(keys[n], "=", values[n])
xh = 2021
xm = liu
xb = male
age = 18
>>> for key, value in zip(keys, values): print(key, "=", value)
xh = 2021
xm = liu
xb = male
age = 18

注意:

循环变量n作为索引标识,访问并打印输出列表元素;内置函数zip()作为并行迭代工具,可将若干个序列打包,返回一个由元组组成的对象,可用list()转换成列表输出

range对象的使用格式:range(start, stop[, step])

range返回的数值系列从start开始到stop结束(不含stop),如给定step,序列按步长step增长,默认为1.只写一个参数,默认是stop,若stop为正,则默认start = 0,step = 1;若为负,则返回空

注意:

range(100)是创建[0, 100)区间整数序列,其中0为起始值(默认),100为结束值,整数序列不包含结束值;range(1, 100, 2)是创建[0, 100)区间奇数序列,其中0为起始值,100为结束值,2为步长

**【例3-11】**用户输入一个正整数N,计算从1到N(包含1和N)相加之后的结果

思路分析:

(1) 根据range()产生1至N之间的整数序列对象,即range(1, N + 1)

(2) 遍历range(1, N + 1)求和

程序代码:

n = int(input("请输入整数N:"))
s = 0
for i in range(n + 1):
    s += i
print("1到N的和是:{}".format(s))

运行结果:

请输入整数N:100
1到N的和是:5050

**【例3-12】**采用for语句输出水仙花数。所谓水仙花数是指一个三位整数,其各位数字的立方(三次幂)之和等与该数本身

思路分析:

(1) 根据range()对象产生所有三位数,即range(100, 1000)

(2) 采用for语句遍历range(100, 1000),输出水仙花数

程序代码:

for n in range(100, 1000):
    ge = n % 10
    shi = n // 10 % 10
    bai = n // 100
    if ge ** 3 + shi ** 3 + bai ** 3 == n: print(n)

运行结果:

153
370
371
407

**【例3-13】**计算1 + 2! + 3! + … + 10!的结果

程序代码:

s = 0
t = 1
for i in range(1, 11):
    t *= i # 有疑问
    s += t
print("运算结果是:{}".format(s))

运行结果:

运算结果是:4037913

3.4.2 while循环语句

语法格式:

while 循环条件:
    循环体

其中:

(1) while是保留字,提示后面语句是while循环语句

(2) 循环条件是一个条件表达式

(3) 冒号(:)是不可缺少的,表示后面是满足循环条件后要执行的语句块

(4) 循环体是由单层或多层缩进语句组成

while循环语句的执行过程:首先判断循环条件是否成立,若成立,则执行循环体,循环体执行完后再判断循环条件是否成立,直到循环条件不成立,退出循环后执行while语句后面的语句

死循环:while循环语句中循环条件一值为真(True),则循环将变为无限循环,程序将一直运行下去。程序死循环时,会造成程序没有任何响应,或造成不断输出(例如控制台输出、文件写入、打印输出等)

注意:

有些程序算法十分复杂,可能需要运行很长时间,但并不是死循环。上述情况都可以使用快捷键 + 终止当前程序的运行

**【例3-14】**采用while语句计算1至100的和

程序代码:

sum = 0
n = 1
while n <= 100:
    sum += n
    n += 1
print("1+2+3+...+100=", sum)

运行结果:

1+2+3+...+100= 5050

**【例3-15】**采用while语句输出四叶玫瑰数。四叶玫瑰数是指一个四位整数,其各位上数字的四次方(四次幂)之和等与该数本身

程序代码:

n = 1000
while n < 10000:
    ge = n % 10
    shi = n // 10 % 10
    bai = n // 100 % 10
    qian = n // 1000
    if ge ** 4 + shi ** 4 + bai ** 4 + qian ** 4 == n: print(n)
    n += 1

运行结果:

1634
8208
9474

**【例3-16】**采用while语句根据近似公式求自然对数的底数为e的值,直到最后一项绝对值小于10-6为止

e ≈ 1 + 1 1 ! + 1 2 ! + . . . + 1 n ! e≈1+ \frac{1}{1!}+\frac{1}{2!}+...+\frac{1}{n!} e1+1!1+2!1+...+n!1

程序代码:

e = 1
n = 1
m = 1
while 1 / n >= pow(10, -6):
    n *= m # 求阶乘
    e += 1 / n
    m += 1
print("e=", e)

运行结果:

e= 2.7182818011463845

3.4.3 循环嵌套语句

循环嵌套是指一个循环语句的循环体内又包含另一个完整的循环结构。通常,内嵌的循环语句称为内循环,而包含内循环的循环语句称为外循环。内循环中还可以嵌套循环,从而形成多层循环结构。for循环、while循环都可以嵌套,相同或不同的循环结构之间都可以互相嵌套多层。但是,每一层的循环在逻辑上必须是完整的

**【例3-17】**采用循环嵌套打印输出九九乘法表

程序代码:

for x in range(1, 10):
    s = ""
    for y in range(1, x + 1):
        s += "{0:1}*{1:1}={2:<2} ".format(x, y, x * y) # <表示左对齐,后面的2表示位数
    print(s)

运行结果:

1*1=1  
2*1=2  2*2=4  
3*1=3  3*2=6  3*3=9  
4*1=4  4*2=8  4*3=12 4*4=16 
5*1=5  5*2=10 5*3=15 5*4=20 5*5=25 
6*1=6  6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 
7*1=7  7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 
8*1=8  8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 
9*1=9  9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 

**【例3-18】**采用循环嵌套输出由1、2和3三个数字组成的且每位数都不相同的三位数

程序代码:

digits = (1, 2, 3)
for x in digits:
    for y in digits:
        for z in digits:
            if x != y and y != z and x != z:
                print(x * 100 + y * 10 + z)

运行结果:

123
132
213
231
312
321

【育德悟道】

循环结构就好比我们周而复始的日常生活,虽然平淡,但如果我们每天坚持学习新知识,那么经过一个时间周期后,我们会发现自身能力得到显著提升。所以我们应该在平淡的生活中积能蓄势,寻找生活亮点,积极乐观地面对每一天

3.4.4 break语句和continue语句

break语句和continue语句是for循环或while循环循环体中的特殊语句,通常用在选择结构语句中,满足一定条件时执行,从而中断正常的循环控制流程。break和continue是循环结构语句中的两个保留字,用于辅助控制循环执行

1. break语句

break语句用于退出for循环或while循环,即提前结束循环,接着执行循环语句的后继语句。当多个for语句、while语句彼此嵌套时,break语句只应用于最内层的语句,即break语句只能跳出最近的一层循环

**【例3-19】**单循环中break语句应用示例

程序代码:

for ch in "ABCDEFG":
    if ch == "E":
        break # 字符为E时,退出循环
    print(ch, end="")

运行结果:

ABCD

**【例3-20】**循环嵌套中break语句应用示例

程序代码:

for ch in "ABCDEFG":
    for n in range(3):
        if ch == "E": # 字符为E时,退出内循环
            break
        print(ch, end="")

运行结果:

AAABBBCCCDDDFFFGGG

2. continue语句

continue语句仅结束本次循环,并返回到循环的起始处,当循环条件满足时开始执行下一次循环

**【例3-21】**continue语句应用示例

程序代码:

for ch in "ABCDEFG":
    if ch == "E":
        continue # 字符为E时返回到循环起始处
    print(ch, end="")

运行结果:

ABCDFG

3.4.5 带else语句的循环语句

Python中,for循环和while循环都有一个可选的else语句,在循环迭代正常完成之后执行,但如果是以break语句的方式退出循环,则else语句将不被执行

1. for-else语句

for-else语句的语法格式:

for 循环变量 in 可迭代对象:
    循环体
else:
    语句块

2. while-else语句

while-else语句的语法格式:

while 循环条件:
    循环体
else:
    语句块

**【例3-22】**对2至9之间的整数n进行处理,若n是素数则打印输出“是素数!”,否则输出它的最小素数因子与另一个数的乘积

程序代码:

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print("{0:1} = {1:1} * {2:1}".format(n, x, n // x))
            break
    else:
        print("{}是素数!".format(n))

运行结果:

2是素数!
3是素数!
4 = 2 * 2
5是素数!
6 = 2 * 3
7是素数!
8 = 2 * 4
9 = 3 * 3

**【例3-23】**检查列表[90, 110, 60, 345, 567],若列表中所有元素都是偶数,则输出“All even!”,否则输出“Not all even!”

程序代码:

nlist = [100, 120, 60, 123, 456]
for n in nlist:
    if n % 2 != 0:
        print("Not all even")
        break
else:
    print("All even!")

运行结果:

Not all even

3.4.6 推导式

推导式(comprehensions)又称解析式。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。Python支持列表推导式、字典推导式和集合推导式等

1. 列表推导式的语法格式

(1) [表达式 for 循环变量 in 可迭代对象]

(2) [表达式 for 循环变量 in 可迭代对象 if 条件表达式]

(3) [表达式1 if 条件表达式 else 表达式2 for 循环变量 in 可迭代对象]

**【例3-24】**列表推导式实例

程序代码:

>>> list1 = [x * 2 for x in "1234"] # 字符串解析成列表
>>> list2 = [x * 2 for x in range(5)] # range解析成列表
>>> print(list1, list2)
['11', '22', '33', '44'] [0, 2, 4, 6, 8]
>>> m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [m[i][i] for i in range(len(m))] # 对角元素组成的列表
[1, 5, 9]
>>> [x for x in range(5) if x % 2 == 0] # 0-5之间的偶数组成的列表
[0, 2, 4]
>>> [(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1] # (x, y)组成元组列表
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
>>> [x if x > 20 else x * 10 for x in (10, 20, 30, 40, 50)]
[100, 200, 30, 40, 50]

2. 集合推导式的语法格式

(1) {表达式 for 循环变量 in 可迭代对象}

(2) {表达式 for 循环变量 in 可迭代对象 if 条件}

(3) {表达式1 if 条件 else 表达式2 for 循环变量 in 可迭代对象}

**【例3-25】**集合推导式实例

程序代码:

>>> set1 = {x * 2 for x in "1234"}
>>> set2 = {x * 2 for x in (1, 2, 3, 4)}
>>> print(set1, set2)
{'33', '11', '44', '22'} {8, 2, 4, 6}
>>> {x for x in range(5) if x % 2 == 1}
{1, 3}

3. 字典推导式的语法格式

(1) {键表达式:值表达式 for 循环变量, 循环变量 in 可迭代对象}

(2) {键表达式:值表达式 for 循环变量, 循环变量 in 可迭代对象 if 条件表达式}

**【例3-26】**字典推导式实例

程序代码:

>>> strs = ["ABC", "DEF", "GHl", "123"]
>>> {key:value for key, value in enumerate(strs)}
{0: 'ABC', 1: 'DEF', 2: 'GHl', 3: '123'}
>>> dict1 = {"a":1, "b":2, "c":3}
>>> dict2 = {v:k for k, v in dict1.items()}
>>> print(dict1, dict2)
{'a': 1, 'b': 2, 'c': 3} {1: 'a', 2: 'b', 3: 'c'}

3.5 编程控制综合应用

**【例3-27】**编程(leapyear.py)判断某一年是否为闰年。判断闰年的条件是年份能被4整除但不能被100整除,或者能被400整除

程序代码:

# 使用一个逻辑表达式判断闰年
y = int(input("请输入年份:"))
if (y % 4 == 0 and y % 100 != 0) or y % 400 == 0: print("{}年是闰年".format(y))
else: print("{}年不是闰年".format(y))
# 使用if-elif-else语句判断闰年
y = int(input("请输入年份:"))
if y % 400 == 0: print("{}年是闰年".format(y))
elif y % 4 != 0: print("{}年不是闰年".format(y))
elif y % 100 == 0: print("{}年不是闰年".format(y))
else: print("{}年是闰年".format(y))
# 使用嵌套的if语句判断闰年
y = int(input("请输入年份:"))
if y % 400 == 0: print("{}年是闰年".format(y))
else:
    if y % 4 == 0:
        if y % 100 == 0: print("{}年不是闰年".format(y))
        else: print("{}年是闰年".format(y))
    else: print("{}年不是闰年".format(y))

运行结果:

请输入年份:2021
2021年不是闰年

**【例3-28】**编写代码,输出由星号*组成的菱形图案,并且可以灵活控制图案的大小

程序代码:

n = 6
for i in range(1, n):
    print(('*' * i ).center(n * 3))
for i in range(n, 0, -1):
    print(('*' * i).center(n * 3))

运行结果:

        *         
        **        
       ***        
       ****       
      *****       
      ******      
      *****       
       ****       
       ***        
        **        
        * 

**【例3-29】**将100以内的素数存于列表中并打印输出

**思路分析:**素数(prime number)又称质数,是指一个大于1的自然数n,除了1和它本身外,不能被其他自然数(2至n - 1)整除

程序代码:

num = []
for n in range(2, 100):
    for x in range(2, n):
        if n % x == 0: break
    else: num.append(n)
print(num)

运行结果:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

**【例3-30】**输出打印1 × 2 + 2 × 3 + 3 × 4 + … + 99 × 100之和

思路分析: 求和算式1 × 2 + 2 × 3 + 3 × 4 + … + 99 × 100中包括99个数相加。其中,第n个数是n × (n + 1)

程序代码:

sum = 0
n = 1
while n <= 99:
    sum += n * (n + 1)
    n += 1
print("1 × 2 + 2 × 3 + 3 × 4 + … + 99 × 100 =", sum)

运行结果:

1 × 2 + 2 × 3 + 3 × 4 ++ 99 × 100 = 333300

**【例3-31】**输入一个二进制整数,将其转换成十进制数并打印输出

思路分析:

二进制数转换为十进制是按权值展开求和。二进制整数转换为十进制,从最后一位开始算,依次为第0位、1位、2位等,位权依次为2的0次方、2的1次方、2的2次方等。二进制整数第n位的权值就是第n位数(0或1)乘以2的n次方

例如,二进制整数1101转化成十进制数:(1101)2 = 1× 20 + 0 × 21 + 1 × 22 + 1 × 23 = (13)10

程序代码:

numb = input("请输入一个二进制整数n:")
print("内置函数转换结果:", int(numb, 2))
numd = 0
for x in range(0, len(numb)):
    if numb[x] == "1": numd += 2 ** (len(numb) - x - 1)
print("编写程序转换结果:", numd)

运行结果:

请输入一个二进制整数n:1110
内置函数转换结果: 14
编写程序转换结果: 14

**【例3-32】**利用公式 π 4 = 1 − 1 3 − 1 5 − 1 7 + . . . \frac{\pi}{4}=1-\frac{1}{3}-\frac{1}{5}-\frac{1}{7}+... 4π=1315171+...计算 π \pi π的近似值,直到某项绝对值小于10-6为止

程序代码:

s = 0 # 表示累加和
t = 1 # 表示符号
x = 1 # 表示要累加的项
i = 1 # 表示分母
while x >= 1e-6:
    x = 1 / i
    s += t * x
    t = -t
    i += 2
s *= 4
print("π的近似值为:{}".format(s))

运行结果:

π的近似值为:3.1415946535856922

**【例3-33】**输入一个大于1的正整数n,将n分解为多个素数因子的乘积。例如,126可被分解为2 × 3 × 3 × 7

思路分析:

根据算术基本定理,任何一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数因子的乘积。2是最小的质数

对n进行分解质因数时,首先应该找到一个最小的质数m,然后按下述步骤完成:

(1) 如果m等于n,则说明分解质因数的过程已经结束,打印输出m即可

(2) 如果n能被m整除,则打印输出m值,并用n除以m的商作为新的正整数n,返回步骤(1)

(3) 如果n不能被m整除,则用m + 1作为m的值,重复执行步骤(1)

程序代码:

n = int(input("请输入一个正整数n:"))
print("{} = ".format(n), end = "")
for m in range(2, n + 1):
    while n % m == 0:
        if m == n:
            print(m)
            break
        else:
            print("{} * ".format(m), end = "")
            n /= m

运行结果:

请输入一个正整数n:120
120 = 2 * 2 * 2 * 3 * 5

**【例3-34】**输入正整数n(3 ≤ n < 1000),计算有多少对素数的和等于输入的这个正整数,并输出结果。注意:输入值小于1000。例如,输入10,则有(5, 5)和(3, 7)两对质数的和为10,输出结果为2

**思路分析:**首先计算出3至n内所有素数,然后找到符合条件的素数对

程序代码:

n = int(input("请输入正整数n(3 ≤ n < 1000):"))
slist = []
for m in range(2, n):
    for x in range(2, m):
        if m % x == 0: break
    else:
        slist.append(m) # 存放3-n的所有素数
count = 0
for x in slist:
    for y in slist:
        if n == x + y and x <= y: # x < y可避免重复
            print("(%s, %s)" % (x, y), end = " ")
            count += 1
print("\ncount = %s" % count)

运行结果:

请输入正整数n(3 ≤ n < 1000)200
(3, 197) (7, 193) (19, 181) (37, 163) (43, 157) (61, 139) (73, 127) (97, 103) 
count = 8

本章小节

本章主要介绍了程序设计的三种控制结构,分别是顺序结构、分支结构和循环结构,围绕这三种结构重点介绍了以下几点内容:

  1. 利用if语句实现分支结构,if语句有四种句式,分别是单分支if语句、双分支if语句、多分支if语句和嵌套if语句
  2. 在嵌套if语句中,注意if和else之间的配对关系
  3. 分支结构的控制条件通常用关系表达式或逻辑表达式结构,也可以是一般表达式结构。因为表达式的值非0为“真”,0为“假”,所以具有值的表达式均可作为if语句的控制条件
  4. Python提供for和while两种循环句式,都可以与else子句结合使用,当循环条件表达式不满足而自然结束时,执行else子句中的代码
  5. break语句用来提前结束其所在for循环或while循环,当多个循环彼此嵌套时,break语句只应用于最内层循环;如果循环是因为执行break语句而结束,则不执行else子句中的代码
  6. continue语句用来提前结束本次循环并进入下一次循环

课后习题

三、综合应用题

  1. 编程计算下列分段函数值:

    y = { 2 x 4 − 3 x 3 x < 0 e 2 x = 0 3 2 x x < 0 y=\left\{\begin{matrix} 2x^4-3x^3 &x<0 \\ e^2&x=0 \\3\sqrt{2x}&x<0 \end{matrix}\right. y= 2x43x3e232x x<0x=0x<0

    程序代码:

    x = int(input("请输入x的值:"))
    if x < 0:
        print("计算结果为:", 2 * pow(x, 4) - 3 * pow(x, 3))
    elif x == 0:
        print("计算结果为:", pow(math.e, 2))
    else:
        print("计算结果为:", 3 * pow(2 * x, 0.5))
    

    运行结果:

    请输入x的值:618
    计算结果为: 105.47037498748168
    
  2. 编写程序实现以下功能:求满足1+2+3+4+…+n>2020的最小n并输出(要求用循环实现)

    程序代码:

    n = 0
    sum = 0
    while sum <= 2020:
        n += 1
        sum += n
    print("最小的n为:", n)
    

    运行结果:

    最小的n为: 64
    
  3. 给出一个小于1000的正整数,编程求该数是几位数,并按逆序打印各位上的数字。例如:原数为456,则输出为654

    程序代码:

    # 精致版——每连续错误三次,给出提示
    import random
    errTimes = 0 # 错误次数
    number = input("请输入一个小于1000的正整数(例如:{}):".format(random.randint(1, 999)))
    while True:
        if (number.isnumeric() and int(number) < 1000):
            print("该数是{0}位数".format(len(str(number))))
            print("逆序为:",str(number)[::-1])
            break
        else:
            errTimes += 1
            if errTimes != 0 and errTimes % 3 == 0:
                print(f"您已错误输入{errTimes}次,如果您想提前结束程序请输入(E/e),输入其他内容将继续本程序")
                result = input("请输入您的选择:")
                if result == "E" or result == "e":
                    print("程序已结束,祝您生活愉快!再见!")
                    break
                else:
                    number = input("请输入一个小于1000的正整数(例如:{}):".format(random.randint(1, 999)))
                    continue
            number = input("您输入的是非法内容,请输入一个小于1000的正整数(例如:{}):".format(random.randint(1, 999)))
    

    运行结果:

    请输入一个小于1000的正整数(例如:229)229
    该数是3位数
    逆序为: 922
    
  4. 输入一个字符串,编程统计并输出其中的大写英文字母和数字的个数

    程序代码:

    content = input("请输入要进行判断的字符串:")
    unumber = 0 # 初始化大写英文字母数量
    dnumber = 0 # 初始化数字数量
    for i in content:
        if i.isupper():
            unumber += 1
        elif i.isdigit():
            dnumber += 1
    print("大写英文字母有{}个,数字有{}个".format(unumber, dnumber))
    

    运行结果:

    请输入要进行判断的字符串:Hello 176
    大写英文字母有1个,数字有3
  5. 编程统计100-1000之间所有素数的个数,并输出它们的和

    程序代码:

    count = 0 # 初始化素数个数
    sum = 0 # 初始化素数的和
    for i in range(100, 1001):
        for j in range(2, int(pow(i, 0.5)) + 1):
            if i % j == 0: break
        else:
            count += 1
            sum += i
    print("100~1000之间所有素数的个数为:{},它们的和为:{}".format(count, sum))
    

    运行结果:

    100~1000之间所有素数的个数为:143,它们的和为:75067
    
  6. 统计并输出500到2020之间所有能被7整除且个位数字为2的数的个数(要求用循环实现)

    程序代码:

    count = 0 # 初始化个数
    for i in range(500, 2021):
        if i % 7 == 0 and str(i)[-1] == "2":
            count += 1
    print("500到2020之间所有能被7整除且个位数字为2的数的有{}个".format(count))
    

    运行结果:

    5002020之间所有能被7整除且个位数字为2的数的有22
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值