Python系列文章目录
第一章 Python 入门
第二章 Python基本概念
第三章 序列
第四章 控制语句
控制语句
前言
本章主要介绍控制语句的三种类型: 顺序结构, 选择结构, 循环结构.
而顺序结构无需多言, 主要注意缩进即可. 重点则是选择结构和循环结构
选择结构主要包括: 单分支, 双分支, 多分支
循环结构主要包括: while循环, for 循环, 嵌套循环.
最后介绍几种生成序列的推导式: 列表推导式, 字典推导式, 集合推导式以及生成器推导式
一、控制语句是什么
控制语句:把语句组合成能完成一定功能的小逻辑模块。
控制语句的分类
分为三类:顺序、选择和循环
- “顺序结构”代表 “先执行a,再执行b” 的逻辑。比如,先找个女朋友,再给女朋友打电话;先订婚,再结婚;
- “条件判断结构”代表 “如果…,则…” 的逻辑。比如,如果女朋友来电,则迅速接电话;如果看到红灯,则停车;
- “循环结构”代表 “如果…,则重复执行…” 的逻辑。比如,如果没打通女朋友电话,则再继续打一次; 如果没找到喜欢的人,则再继续找
二、选择结构
选择结构通过判断条件是否成立,来决定执行哪个分支。选择结构
有多种形式,分为:单分支、双分支、多分支
1. 单分支选择结构
单分支语句流程图如下图所示
if语句单分支结构的语法形式如下:
if 条件表达式:
语句/语句块
注意:
- 条件表达式:可以是逻辑表达式、关系表达式、算术表达式等等。
- 语句/语句块:可以是一条语句,也可以是多条语句。多条语句,缩进必须对齐一致
实操代码
# 【操作】输入一个数字,小于10,则打印这个数字
num = input("请输入付款金额: ")
if int(num) < 100:
print("没法找零, 请稍后再次输入~~~")
条件表达式
注意事项:
- 在选择和循环结构中,条件表达式的值为 False 的情况如下:
False、0、0.0、空值None、空序列对象(空列表、空元祖、空集合、空字典、空字符串)、空range对象、空迭代对象。其他情况,均为 True 。 - 条件表达式中,不能有赋值操作符 =
实操代码
if 3:
print("1.条件为True")
a = []
if a:
print("2.条件为False") # if 显示默认为 true 的条件, 因此这里没打印
b = ""
if b:
print("3.条件为False") # if 显示默认为 true 的条件, 因此这里没打印
c = "False"
if c:
print("4.条件为False") # 这里字符串不为null, 因此条件成立(True), 因此会打印
a = 5
if 4 < a < 6:
print("5.大于四小于六的整数是五")
# 条件表达式中,不能有赋值操作符 =
# 在Python中,条件表达式不能出现赋值操作符 = ,避免了其他语言中经常误将关系运算符 == 写作赋值运算符 = 带来的困扰。
# 如下代码将会报语法错误:
# if 3 < c and (c=20): #直接报语法错误! Unexpected expression syntax
# print("赋值符不能出现在条件表达式中")
2. 双分支选择结构
双分支语句流程图如下图所示
双分支结构的语法格式如下
if 条件表达式:
语句1/语句块1
else:
语句2/语句块2
实操代码
# 输入一个数字,小于100,则提示付款成功;大于100,则提示无法找零, 请稍后再次输入”
num = input("请输入付款金额: ")
if int(num) < 100:
print("无法找零, 请稍后再次输入~~~")
else:
print("恭喜您付款成功! 付款金额:", num)
三元条件运算符
三元条件运算符语句流程图如下图所示
三元条件运算符语法格式如下:
条件为真时的值 if (条件表达式) else 条件为假时的值
实操代码
可以看到, 这种写法更加简洁易读.
但是如果需要在 else 传变量时, 需要加括号, 防止变量的参数渗透到其他逻辑上(除非逻辑本意要求如此)
# 三元条件运算符
# 符语法格式: 条件为真时的值 if (条件表达式) else 条件为假时的值
# 可以看到, 这种写法更加简洁易读. 但是如果需要在 else 传变量时需要加括号, 防止变量的参数渗透到其他逻辑上(除非逻辑本意要求如此)
# num = input("请输入付款金额: ")
print("无法找零, 请稍后重新输入~~~" if int(num) < 100 else "恭喜您付款成功!, 付款金额:", num) # 如果输入1, 则会返回: 无法找零, 请稍后重新输入~~~ 1
print("无法找零, 请稍后重新输入~~~" if int(num) < 100 else ("恭喜您付款成功!, 付款金额:", num)) # 如果输入1, 则会返回: 无法找零, 请稍后重新输入~~~
3. 多分支选择结构
多分支选择结构语法格式如下:
多分支选择结构的语法格式如下
if 条件表达式1 :
语句1/语句块1
elif 条件表达式2:
语句2/语句块2
...
elif 条件表达式n :
语句n/语句块n
[else:
语句n+1/语句块n+1
]
# 注:计算机行业,描述语法格式时,使用中括号 [ ] 通常表示可选,非必选
注意:
- 多分支结构,几个分支之间是有逻辑关系的,不能随意颠倒顺序
- 单分支结构: 每个分支都使用了独立的、完整的判断,顺序可以随意挪动,而不影响程序运行
实操代码
# 【操作】输入一个学生的成绩,将其转化成简单描述:不及格(小于60)、及格(60-79)、良好(80-89)、优秀(90-100)
# 1. 使用多分支语句: 几个分支之间是有逻辑关系的,不能随意颠倒顺序
num = input("请录入学生分数: ")
if int(num) < 60:
print("该生不及格!")
elif int(num) < 79:
print("该生及格")
elif int(num) < 89:
print("该生良好")
elif int(num) <= 100:
print("该生优秀")
# 2. 使用单分支语句: 每个分支都使用了独立的、完整的判断,顺序可以随意挪动,而不影响程序运行
num = input("请录入学生分数: ")
if int(num) < 60:
print("该生不及格!")
if 60 <= int(num) < 79:
print("该生及格")
if 79 <= int(num) < 89:
print("该生良好")
if 89 <= int(num) <= 100:
print("该生优秀")
# 【操作】已知点的坐标(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("该坐标位于第四象限")
选择结构嵌套
选择结构可以嵌套,使用时一定要注意控制好不同级别代码块的缩进量,因为缩进量决定了代码的从属关系
实操代码
# 【操作】输入一个分数。分数在0-100之间。90以上是A,80以上是B,70以上是C,60以上是D。60以下是E
score = int(input("请录入学生分数 (1-100):"))
x = "E"
if 0 <= score <= 100:
if score >= 90:
x = "A"
elif score >= 80:
x = "B"
elif score >= 70:
x = "C"
elif score > 60:
x = "D"
print("该学生分数是: {0}, 该学生的等级是: {1}".format(score, x))
else:
print("录入分数超出范围 1-100 ")
# 体会优化版为什么要这么写
score = int(input("请输入一个在0-100之间的数字:"))
degree = "ABCDE"
num = 0
if score > 100 or score < 0:
score = int(input("输入错误!请重新输入一个在0-100之间的数字:"))
else:
num = score // 10
if num >= 9:
num = 9
if num < 6:
num = 5
print("分数是{0},等级是{1}".format(score, degree[9 - num]))
# 答: //: 整数除法, 利用十位数num来做文章
# 将 num 与 9 - num 进行关联, 的出来的结果作为 字符串序列的下标, 然后根据下标来访问对应的数据
三、循环结构
循环结构用来重复执行一条或多条语句。
表达这样的逻辑:如果符合条件,则反复执行循环体里的语句。
在每次执行完后都会判断一次条件是否为True,如果为True则重复执行循环体里的语句。图示如下:
循环结构语法格式如下:
1. while循环
while循环的语法格式如下:
while 条件表达式:
循环体语句
实操代码
# 【操作】利用while循环打印从0-10的数字
num = 0
while num < 10:
print(num)
num += 1
# 【操作】利用while循环,计算1-100之间数字的累加和;计算1-100之间偶数的累加和,计算1-100之间奇数的累加和
num = 1
total_num = 0
total_even = 0
total_odd = 0
while num <= 100:
total_num += num
if num % 2 == 0:
total_even += num
else:
total_odd += num
num += 1
print("所有数字累加和: {0}, 所有奇数和: {1}, 所有偶数和: {2}".format(total_num, total_odd, total_even))
2. for 循环
for循环通常用于可迭代对象的遍历。
for循环的语法格式如下:
for 变量 in 可迭代对象:
循环体语句
实操代码如下
# 循环体语句
for x in (20, 30, 40):
print(x * 3)
可迭代对象
Python包含以下几种可迭代对象:
- 序列. 包含:字符串、列表、元组、字典、集合
- 迭代器对象(iterator)
- 生成器函数(generator)
- 文件对象
实操代码
# 【操作】遍历字符串中的字符
for x in "TimePause":
print(x)
# 【操作】遍历字典
a = {
"name": "巨亨队", "season": 3, "winner": "卡罗尔"}
for x in a:
print(a)
for x in a.keys():
print(x)
for x in a.values():
print(x)
for x in a.items():
print(x)
range 对象
range对象 是一个迭代器对象,用来产生指定范围的数字序列。
语法格式为:
range(start, end [,step])
注意:
生成的数值序列从 start 开始到 end 结束(不包含 end ). 若没有填写 start ,则默认从0开始。
step 是可选的步长,默认为1. 如下是几种典型示例:
# range(10) 产生序列:0 1 2 3 4 5 6 7 8 9
# range(3,10) 产生序列:3 4 5 6 7 8 9
# range(3,10,2) 产生序列:3 5 7 9
实操代码
# 利用for循环,计算1-100之间数字的累加和;计算1-100之间偶数的累加和,计算1-100之间奇数的累加和
total_num = 0
total_odd = 0
total_even = 0
for x in range(101): # 生成的数值序列从 start 开始到 end 结束但不包括end
total_num += x
if x % 2 == 0:
total_even += x
else:
total_odd += x
print("所有数字累加和: {0}, 所有奇数和: {1}, 所有偶数和: {2}".format(total_num, total_odd, total_even))
使用zip()并行迭代多个序列
我们可以通过zip()函数对多个序列进行并行迭代,zip()函数在最短序列“用完”时就会停止。
实操代码
# 【操作】测试zip()并行迭代
names = ("Time", "Pause", "Git", "Lib")
ages = (18, 16, 20, 25)
jobs = ("老师", "程序员", "公务员")
for name, age, job in zip(names, ages, jobs):
print("{0}--{1}--{2}".format(name, age, job))
# 不适用zip,也可以并行迭代多个序列
for i in range(min(len(names), len(ages), len(jobs))):
print("{0}--{1}--{2}".format(names[i], ages[i], jobs[i]))
3. 嵌套循环
一个循环体内可以嵌入另一个循环,一般称为“嵌套循环”,或者“多重循环”。
实操问题1: 打印如下图案
实操代码
核心: 利用print 函数的 end 参数来实现打印的不换行输出
# 一个循环体内可以嵌入另一个循环,一般称为“嵌套循环”,或者“多重循环”
for x in range(5):
for y in range(5):
print(x, end="\t")
print()
实操问题2: 利用嵌套循环打印小九九(九九乘法表)
实操代码
# 【操作】利用嵌套循环打印九九乘法表
for x in range(1, 10):
for y in range(1, 10):
if y <= x:
print(x, "*", y, "=", y * x, end="\t")
print()
# 这种方式是提前规划好m的值
for m in range(1, 10):
for n in range(1, m + 1):
print("{0}*{1}={2}".format(m, n, (m * n)), end="\t")
print()
实操问题3: 用列表和字典存储下表信息,并打印出表中工资高于15000的数据
# 【操作】用列表和字典存储下表信息,并打印出表中工资高于15000的数据
r1 = dict(name="Time", age=18, salary=30000, city="北京")
r2 = dict(name="Pause", age=19, salary=20000, city="上海")
r3 = dict(name="Market", age=20, salary=10000, city="深圳")
tb = [r1, r2, r3]
for x in tb:
if x.get("salary") > 15000:
print(x)
4. 循环中断语句
循环中断语句语法格式如下:
continue
continue语句用于结束本次循环,继续下一次循环。
多个循环嵌套时,continue也是应用于最近的一层循环。
实操代码
# 【操作】要求输入员工的薪资,若薪资小于0则重新输入. 最后打印出录入员工的数量和薪资明细,以及平均薪资
empNum = 0
salarySum = 0
salarys = []
while True:
s = input("请输入员工的薪资(按Q或q结束)")
if s.upper() == 'Q':
print("录入结束")
break # 满足当前条件后, 跳出while循环
if float(s) < 0:
print("无效!继续录入!")
continue # 满足条件后, 跳出当前循环, 执行下一次while循环
print("录入成功!")
empNum += 1
salarys.append(float(s))
salarySum += float(s)
print("员工数{0}".format(empNum))
print("录入薪资:", salarys)
print("总发薪资:", salarySum)
print("平均薪资{0}".format(salarySum / empNum))
berak
break语句可用于while和for循环,用来结束整个循环.
当有嵌套循环时,break语句只能跳出最近一层的循环.
实操代码
# 【操作】使用break语句结束循环
while True:
a = input("请输入一个字符(输入Q或q结束)")
if a.upper() == 'Q':
print("循环结束,退出")
break
else:
print(a)
else 语句
while、for循环可以附带一个else语句(可选).
如果for、while语句没有被break语句结束,则会执行else子句,否则不执行.
语法格式如下:
while 条件表达式:
循环体
else:
语句块
或者:
for 变量 in 可迭代对象:
循环体
else:
语句块
实操代码
# 【操作】员工一共4人。录入这4位员工的薪资。全部录入后,打印提示“您已经全部录入4名员工的薪资”。最后,打印输出录入的薪资和平均薪资
salarySum = 0
salarys = []
for i in range(4): # 控制遍历4次
s = input("请输入一共4名员工的薪资(按Q或q中途结束)")
if s.upper() == 'Q':
print("录入完成,退出")
break # 输入q/Q则直接退出
if float(s) < 0:
continue # 如果输入的数值小于0 则不进行后面的计算
salarys.append(float(s))
salarySum += float(s)
else: # 上面循环执行完毕后, 输出统计信息
print("您已经全部录入4名员工的薪资")
print("录入薪资:", salarys)
print("平均薪资{0}".format(salarySum / 4))
5. 循环代码优化
虽然计算机越来越快,空间也越来越大,我们仍然要在性能问题上“斤斤计较”.
编写循环时,遵守下面三个原则可以大大提高运行效率,避免不必要的低效计算:
- 尽量减少循环内部不必要的计算
- 嵌套循环中,尽量减少内层循环的计算,尽可能向外提
- 局部变量查询较快,尽量使用局部变量
优化案例代码
import time
start = time.time()
for i in range(1000):
result = []
for m in range(10000):
c = i * 1000 # 提到外部循环
# result = result + [m * 100] #不使用拼接,会产生大量新对象
result.append(c + m * 100)
end = time.time()
print("耗时:{0}".format((end - start)))
print("简单循环优化后...")
start2 = time.time()
for i in range(1000):
result = []
c = i * 1000
for m in range(10000):
result.append(c + m * 100)
end2 = time.time()
print("耗时:{0}".format((end2 - start2)))
运行结果
补充原则
- 连接多个字符串,使用join()而不使用+
- 列表进行元素插入和删除,尽量在列表尾部操作
四、利用推导模式创建序列(重点)
推导式是从一个或者多个迭代器快速创建序列的一种方法.
它可以将循环和条件判断结合,从而避免冗长的代
推导式是典型的Python风格
1. 列表推导式
列表推导式生成列表对象,语法如下
[表达式 for item in 可迭代对象 ]
# 或者:
{
表达式 for item in 可迭代对象 if 条件判断}
实操代码
print([x for x in range(1, 5)]) # [1, 2, 3, 4]
print([x * 2 for x in range(1, 5)]) # [2, 4, 6, 8]
print([x * 2 for x in range(1, 20) if x % 5 == 0]) # [10,20, 30]
print([a for a in "abcdefg"]) # ['a', 'b', 'c','d', 'e', 'f', 'g']
# 可以使用两个循环,使用zip并行迭代
cells = [(row, col) for row, col in zip(range(1, 10), range(101, 110))]
print(cells)
# 二者对比. 体现推导式的优势
# 使用推导式,生成列表
a = [x for x in range(1, 10) if x % 2 == 0]
print(a)
# 不使用推导式,生成列表
b = []
for x in range(1, 10):
if x % 2 == 0:
b.append(x)
print(b)
2. 字典推导式
字典的推导式生成字典对象,格式如下:
{
key_expression: value_expression for 表达式 in 可迭代对象}
实操代码
# 类似于列表推导式,字典推导也可以增加if条件判断、多个for循环
values = ["北京", "上海", "深圳", "广州"]
cities = {
id * 100: city for id, city in zip(range(1, 5), values)}
print(cities) # {100: '北京', 200: '上海', 300: '深圳', 400: '广州'}
# 统计文本中字符出现的次数
my_text = ' i love you, i love csdn, i love time_pause'
char_count = {
c: my_text.count(c) for c in my_text}
print(char_count)
3. 集合推导式
集合推导式生成集合,和列表推导式的语法格式如下:
{
表达式 for item in 可迭代对象 }
# 或者:
{
表达式 for item in 可迭代对象 if 条件判断}
实操代码
# 输出一个集合, 集合内容是输出1-99中可以整除9的元素
print({
x for x in range(1, 100) if x % 9 == 0})
4. 生成器推导式(不直接生成元组)
python 序列包括: 列表, 字典, 集合, 元组
基于上面的推导式来看,元组能不能用小括号呢?
实操代码
print((x for x in range(1, 100) if x % 9 == 0)) # <generator object <genexpr> at 0x0000023F570FCB30>
# 我们发现打印的是“一个生成器对象”。显然,元组是没有推导式的
# 一个生成器只能运行一次. 第一次迭代可以得到数据,第二次迭代发现数据已经没有了。
gnt = (x for x in range(1, 100) if x % 9 == 0)
for x in gnt:
print(x, end=' ') # 9 18 27 36 45 54 63 72 81 90 99
for x in gnt:
print(x, end=' ') # 无实际元素输出