目录
Python 同样提供了现代编程语言都支持的两种基本流程控制结构:分支结构和循环结构。其中分支结构用于实现根据条件来选择性地执行某段代码:循环结构则用于实现根据循环条件重复执行某段代码。Python 使用if 语句提供分支支持,提供了while 、for-in 循环,也提供了break 和continue 回来控制程序的循环结构。
1. 顺序结构
在任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下一行行地执行,中间没有任何判断和跳转。
python 程序的多行代码之间没有任何流程控制,则程序总是从上向下依次执行,排在前面的代码先执行,排在后面的代码后执行.
2. if 分支结构
if 分支使用布尔表达式或布尔值作为分支条件来进行分支控制。
Python 的if 语句有如下三种形式
# 第一种形式
if expression :
statements ...
# 第二种形式
if expression :
statements ...
else :
statements ...
# 第三种形式
if expression :
statements ...
elif expression :
statements ...
... // 可零条或多条elif
else :
statements ...
if exp ression :、elif expression .及else : 后缩进的多行代码被称为代码块,一个代码块通常被当成一个整体来执行(除非在运行过程中遇到return, break 、continue 等关键字〉,因此这个代码块也被称为条件执行体。
Python 是一门很“独特”的语言,它的代码块是通过缩进来标记的,),具有相同缩进的多行代码属于同一个代码块。如果代码莫名其妙地乱缩进, Python 解释器会报错。
- 代码块一定要缩进, 否则就不是代码块
- 同一个代码块内的代码必须保持相同的缩进,既不能多,也不能少。
- 冒号精确表示代码块的开始,若遗漏,Python 解释器就无法识别代码块的开始点
- if 条件可以是任意类型(当做False处理 : False 、None 、0 、””、()、[]、{})
- 在使用if else 分支语句时, 一定要先处理包含范围史小的情形。
- if 分支语句还可作为表达式,此时if 表达式相当于其他语言中的三目运算符
3. pass 语句
Python 的 pass 语句就是空语句。
有时候程序需要占一个位、放一条语句,但又不希望这条语句做任何事情,此时就可通过pass语句来实现。通过使用pass 语句,可以让程序更完整。
s = input("请输入一个整数: ")
s = int(s)
if s > 5:
print("大于5")
elif s < 5:
# 空语句,相当于占位符
pass
else:
print("等于5")
4. 断言
断言语句和if 分支有点类似,它用于对一个bool 表达式进行断言,如果该bool 表达式为True,该程序可以继绞二向下执行; 否则程序会引发AssertionError 错误。
断言也相当于一种特殊的分支。
类如:
s_age = input("请输入您的年龄:")
age = int(s_age)
assert 20 < age < 80
print("您输入的年龄在20和80之间")
5. 循环结构
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体。当反复执行这个循环体时,需要在合适的时候把循环条件改为假,从而结束循环:否则循环将一直执行下去,形成死循环。
循环语句可能包含如下4 个部分。
- 初始化语句( init statements ) : 一条或多条语句,用于完成一些初始化工作。初始化i吾旬在循环开始之前执行
- 循环条件( test_expression ) : 这是一个布尔表达式,这个表达式能决定是否执行循环体。
- 循环体( body_statements ) :这个部分是循环的主体,如果循环条件允许,这个代码块将被重复执行。
- 迭代语句( iteration statements ) :这个部分在一次执行循环体结束后,对循环条件求值之前执行,通常用于控制循环条件中的变量,使得循环在合适的时候结束。
上面4 个部分只是一般分类,并不是每个循环中都非常清晰地分出这4 个部分。
5.1 while 循环
while 循环的语法格式如下:
[init statements] # 初始化
while test_expression : # 循环条件
body_statements # 循环体
[iteration statements] # 迭代语句
# 循环的初始化条件
count_i = 0
# 当count_i小于10时,执行循环体
while count_i < 10 :
print("count:", count_i)
# 迭代语句
count_i += 1
print("循环结束!")
# 下面是一个死循环
count_i2 = 0
while count_i2 < 10 :
print("不停执行的死循环:", count_i2)
count_i2 -=1
print("永远无法跳出的循环体")
由于列表和元组的元素都是有索引的,因此程序可通过while 循环、列表或元组的索引来遍历列表和元组中的所有元素。
5.2 for - in 循环
for -in 循环专门用于遍历范围、列表、元素和字典等可迭代对象包含的元素。
# for-in 循环的语法格式
for 变量 in 字符串|范围|集合等:
statements
语法格式有两点说明。
- for-in 循环中的变量的值受for-in 循环控制,该变量将会在每次循环开始时自动被赋值,因此程序不应该在循环中对该变量赋值。
- for-in 循环可用于遍历任何可选代对象。所谓可迭代对象,就是指该对象中包含一个iter一方法,且该方法的返回值对象具有next()方法。
for-in 循环中的变量完全接受for-in 循环控制,因此该变量也被称为循环计数器。
程序对for-in 循环的循环计数器赋值在语法上是允许的,但没有什么意义,而且非常容易导致错误。
s_max = input("请输入您想计算的阶乘:")
mx = int(s_max)
result = 1
# 使用for-in循环遍历范围
for num in range(1, mx + 1):
result *= num
print(result)
在使用for-in 循环遍历列表和元组时,列表或元组有几个元素, for-in 循环的循环体就执行几次,针对每个元素执行一次,循环计数器会依次被赋值为元素的值。
src_list = [12, 45, 3.4, 13, 'a', 4, 56, 'crazyit', 109.5]
my_sum = 0
my_count = 0
for ele in src_list:
# 如果该元素是整数或浮点数
if isinstance(ele, int) or isinstance(ele, float):
print(ele)
# 累加该元素
my_sum += ele
# 数值元素的个数加1
my_count += 1
print('总和:', my_sum)
print('平均数:', my_sum / my_count)
如果需要, for-in 循环也可根据索引来遍历列表或元组:只要让循环计数器遍历0 到列表长度的区间,即可通过该循环计数器来访问列表元素。
a_list = [330, 1.4, 50, 'fkit', -3.5]
# 遍历0到len(a_list)的范围
for i in range(0, len(a_list)) :
# 根据索引访问列表元素
print("第%d个元素是 %s" % (i , a_list[i]))
使用for-in 循环遍历字典其实也是通过遍历普通列表来实现的。
字典包含了如下三个方法。
- items (): 返回字典中所有key -value 对的列表
- keys (): 返回字典中所有key 的列表。
- values ():返回字典中所有value 的列表。
my_dict = {'语文': 89, '数学': 92, '英语': 80}
# 通过items()方法遍历所有key-value对
# 由于items方法返回的列表元素是key-value对,因此要声明两个变量
for key, value in my_dict.items():
print('key:', key)
print('value:', value)
print('-------------')
# 通过keys()方法遍历所有key
for key in my_dict.keys():
print('key:', key)
# 在通过key获取value
print('value:', my_dict[key])
print('-------------')
# 通过values()方法遍历所有value
for value in my_dict.values():
print('value:', value)
src_list = [12, 45, 3.4, 12, 'fkit', 45, 3.4, 'fkit', 45, 3.4]
statistics = {}
for ele in src_list:
# 如果字典中包含ele代表的key
if ele in statistics:
# 将ele元素代表出现次数加1
statistics[ele] += 1
# 如果字典中不包含ele代表的key,说明该元素还未出现国
else:
# 将ele元素代表出现次数设为1
statistics[ele] = 1
# 遍历dict,打印出各元素的出现次数
for ele, count in statistics.items():
print("%s的出现次数为:%d" % (ele, count))
5.3 循环使用else
Python 的循环都可以定义else 代码块,当循环条件为False 时,程序会执行else 代码块。(实际很鸡肋)
循环的else 代码块是Python 的一个很特殊的语法(其他编程语言通常不支持), else 代码块的主要作用是便于生成更优雅的Python 代码。
count_i = 0
while count_i < 5:
print('count_i小于5: ', count_i)
count_i += 1
else:
print('count_i大于或等于5: ', count_i)
5.4 for 表达式
for 表达式用于利用其他区间、元组、列表等可迭代对象创建新的列表。
# for 表达式的语法格式
[表达式for 循环计数器且可法代对象]
从上面的语法格式可以看出, for 表达式与普通for 循环的区别有两点。
- 在for 关键字之前定义一个表达式,该表达式通常会包含循环计数器。
- for 表达式没有循环体,因此不需要冒号。
for 表达式当然也是有循环的,它同样会对可迭代对象进行循环一一可迭代对象包含几个对象,该循环就对for 之前的“表达式”执行几次(相当于for 之前的表达式就是循环体),并将每次执行的值收集起来作为新的列表元素。
for 表达式最终返回的是列表,因此for 表达式也被称为列表推导式。
还可以在for 表达式后面添加if 条件,这样for 表达式将只迭代那些符合条件的元素。
如果将for 表达式的方括号改为圆括号, for 表达式将不再生成列表,而是生成一个生成器(generator ),该生成器同样可使用for 循环选代。对于使用圆括号的for 表达式,它最终返回的是生成器,因此这种for 表达式也被称为生成器推导式。
a_range = range(10)
# 对a_range执行for表达式
a_list = [x * x for x in a_range]
# a_list集合包含10个元素
print(a_list)
b_list = [x * x for x in a_range if x % 2 == 0]
# a_list集合包含5个元素
print(b_list)
# 使用for表达式创建生成器
c_generator = (x * x for x in a_range if x % 2 == 0)
# 使用for循环迭代生成器
for i in c_generator:
print(i, end='\t')
print()
d_list = [(x, y) for x in range(5) for y in range(4)]
# d_list列表包含20个元素
print(d_list)
dd_list = []
for x in range(5):
for y in range(4):
dd_list.append((x, y))
print(dd_list)
e_list = [[x, y, z] for x in range(5) for y in range(4) for z in range(6)]
# 3_list列表包含120个元素
print(e_list)
src_a = [30, 12, 66, 34, 39, 78, 36, 57, 121]
src_b = [3, 5, 7, 11]
# 只要y能整除x,就将它们配对在一起
result = [(x, y) for x in src_b for y in src_a if y % x == 0]
print(result)
6. 常用工具函数
使用zip ()函数可以把两个列表“压缩” 成一个zip 对象(可法代对象〉,这样就可以使用一个循环并行遍历两个列表。
# 交互式解释器
>> a = [ ’ a ’,’b ’, ’ c ’ ]
>> b = (1, 2 , 3]
>> [x for x in zip(a , b)]
[ (’ a ’, 1 ) I ( ’ b ’, 2) , ( ’ c ’, 3) ]
zip ()函数压缩得到的可迭代对象所包含的元素是由原列表元素组成的元组。
如果 zip()函数压缩的两个列表长度不相等, 那么 zip()函数将以长度更短的列表为准。
z ip ()函数不仅可以压缩两个列表, 也可以压缩多个列表。
使用z ip()函数压缩N 个列表,那么z ip ()函数返回的可选代对象的元素就是长度为N 的元组。
books = ['疯狂Kotlin讲义', '疯狂Swift讲义', '疯狂Python讲义']
prices = [79, 69, 89]
# 使用zip()函数压缩两个列表,从而实现并行遍历
for book, price in zip(books, prices):
print("%s的价格是: %5.2f" % (book, price))
有些时候, 程序需要进行反向遍历,此时可通过 reversed ()函数,该函数可接收各种序列(元组、列表、区间等)参数, 然后返回一个“反序排列”的法代器,该函数对参数本身不会产生任何影响。
str 其实也是序列,因此也可通过该函数实现在不影响字符串本身的前提下,对字符串进行反序遍历。
与reversed() 函数类似的还有sorted() 函数,该函数接收一个可迭代对象作为参数,返回一个对元素排序的列表。
sorted()函数也不会改变所传入的可迭代对象, 该函数只是返回一个新的、排序好的列表。
在使用sorted()函数时,还可传入一个reverse 参数,如果将该参数设置为True ,则表示反向排序。
在调用sorted()函数时,还可传入一个key 参数,该参数可指定一个函数来生成排序的关键值。比如希望根据字符串长度排序,则可为key 参数传入len 函数。
my_list = ['fkit', 'crazyit', 'Charlie', 'fox', 'Emily']
for s in sorted(my_list, key=len):
print(s)
7. 控制循环结构
Python 语言没有提供goto 语句来控制程序的跳转,这种做法虽然提高了程序流程控制的可读性,但降低了灵活性。为了弥补这种不足, Python 提供了continue 和break 来控制循环结构。除此之外,使用 return 可以结束整个方法,当然也就结束了一次循环。
7.1 使用break 结束循环
break 用于完全结束一个循环,跳出循环体。
与C类似。
# 一个简单的for循环
for i in range(0, 10) :
print("i的值是: ", i)
if i == 2 :
# 执行该语句时将结束循环
break
在使用break 语句的情况下,循环的else 代码块与直接放在循环体后是有区别的如果将代码块放在else 块中,当程序使用break 中止循环时,循环不会执行else块; 如果将代码块直接放在循环体后面,当程序使用break 中止循环时,程序自然会执行循环体之后的代码块。
# 一个简单的for循环
for i in range(0, 10) :
print("i的值是: ", i)
if i == 2 :
# 执行该语句时将结束循环
break
else:
print('else块: ', i)
# 循环嵌套
exit_flag = False
# 外层循环
for i in range(0, 5) :
# 内层循环
for j in range(0, 3 ) :
print("i的值为: %d, j的值为: %d" % (i, j))
if j == 1 :
exit_flag = True
# 跳出里层循环
break
# 如果exit_flag为True,跳出外层循环
if exit_flag :
break
7.2 使用continue 忽略本次循环的剩下语句
continue 只是忽略当次循环的剩下语句, 接着开始下一次循环, 并不会中止循环
与C类似。
# 一个简单的for循环
for i in range(0, 3 ) :
print("i的值是: ", i)
if i == 1 :
# 忽略本次循环的剩下语句
continue
print("continue后的输出语句")
7.3 使用return 结束方法
return 用于从包围它的最直接方法、函数或匿名函数返回。不管return 处于多少层循环之内。
与C类似。
def test() :
# 外层循环
for i in range(10) :
for j in range(10) :
print("i的值是: %d, j的值是: %d" % (i , j))
if j == 1 :
return
print("return后的输出语句")
test()