程序有三种基本的控制结构:顺序结构、选择结构、循环结构。
顺序结构:
选择结构(分支结构):
循环结构:
3.1 条件语句
条件语句是通过判断条件是否成立,根据条件表达式的结果做出决策,控制不同代码块的执行。
3.1.1 条件表达式
条件表达式由运算符和操作数组成
例如:a<4,其中a、4都是操作数,小于符号<是运算符
判断条件可以是具有布尔属性的任意元素,包括数据、变量或由变量与运算符组成的表达式,若其布尔属性为True,条件成立;若布尔属性为False,条件不成立。
除了非空常量外,Python还常使用关系操作符和成员运算符构成判断条件 。
条件表达式常用的运算符有:
算术运算符:+、-、*、/、//、%、**
关系运算符:
Python支持通过保留字not、and和or对判断条件进行逻辑组合:
- not,表示单个条件的“否”关系。如果“条件”的布尔属性为True,“not 条件”的布尔属性就为False;如果“条件”的布尔属性为False,“not 条件”的布尔属性就为True。
- and,表示多个条件之间的“与”关系。当且仅当使用and连接的所有条件的布尔属性都为True时,逻辑表达式的布尔属性为True,否则为False。
- or,表示多个条件之间的“或”关系。当且仅当使用or连接的所有条件的布尔属性都是False时,逻辑表达式的布尔属性为False,否则为True。
3.1.2 单分支选择结构
- 若if语句中的判断条件成立,执行if语句后的代码段;
- 若判断条件不成立,则跳过if语句后的代码段。
- 单分支结构中的代码段只有“执行”与“跳过”两种情况。
示例:使用单分支结构判断当天是否是星期天。
day = int(input("今天是工作日吗(请输入整数1~7)?"))
if day in [1,2,3,4,5]:
print("今天是工作日。")
if day in [6,7]:
print("今天非工作日。")
3.1.3 双分支选择结构
- 若if语句中的判断条件成立,执行代码段1
- 若判断条件不成立,则执行代码段2
示例:使用二分支结构判断当天是否是工作日。
day = int(input("今天是工作日吗(请输入整数1~7)?"))
if day in [1,2,3,4,5]:
print("今天是工作日。")
else:
print("今天非工作日。")
3.1.4 多分支选择结构
3.1.5 选择结构的嵌套
选择结构的嵌套是指选择结构的内部包含选择结构
3.1.6 三元表达式
python中没有c语言中的三目运算符,但是可以通过以下的形式实现三目运算符的功能
格式:条件判断为真时的结果 if 判断条件 else 条件为假时的结果
示例:x=x-1 if x>0 else x=x+1
等价于:
if x > 0:
x = x - 1
else:
x = x + 1
我们可以利用三元表达式来实现裴波那契数列:
def fun(n):
return n if n < 2 else fun(n - 1) + fun(n - 2)
还有一种用法,用bool方法选择相应的值,例如:
x = 1
print([2, 3][bool(x)])
x = 0
print([2, 3][bool(x)])
结果:
3
2
3.2 循环语句
在实际应用中有些需要重复进行的操作,可以用循环语句实现。
循环语句有:
while、do while、for
3.2.1 while循环
- 若循环条件为True,则循环执行while循环中的代码段;
- 若循环条件为False,终止while循环。
- 若while循环的条件总是True,这种情况叫做死循环 。
例如:使用while循环实现计算n的阶乘
n = int(input("请输入一个整数:"))
fact = 1
i = 1
while i<= n:
fact = fact*i
i = i + 1
print("n!={}".format(fact))
3.2.2 while else循环
Python的while循环也支持使用保留字else产生分支。
示例2:使用while-else循环实现计算n的阶乘
n = int(input("请输入一个整数:"))
fact = 1
i = 1
print("n!计算中……")
while i<= n:
fact = fact*i
i = i + 1
else:
print("n!计算完成 ,循环正常结束")
print("n!={}".format(fact))
3.2.3 for 循环
- 目标可以是字符串、文件、range()函数或组合数据类型等;
- 循环变量用于保存本次循环中访问到的遍历结构中的元素;
- for循环的循环次数取决于遍历的目标元素个数。
示例1:遍历字符串中的每个字符
string = input("请输入一个字符串:")
for c in string:
print(c)
3.2.4 for else循环
for....else循环的具体实现形式:
for 循环变量 in 目标:
循环体
else:
代码块
用法与while...else相同,如果循环体结束后没有碰到break语句,就会执行else语句块,如果结束之前碰到了break语句,就会跳出整个for循环,因此else语句块也就不会执行。
3.3 循环控制语句
·在循环语句中,有时候需要达到中断循环,或者跳过本次循环,执行下次循环的情况,因此就需要有循环控制语句
python中使用break、continue语句控制循环的执行过程
break用于跳出整个循环
continue用于跳出本次循环,继续执行下次循环
3.3.1 break语句
3.3.2 continue语句
3.3.3 pass语句
pass的意思是过,pass掉就是淘汰掉的意思。
在python中,pass的意思是空语句,pass语句不做任何事情,只是为了保持程序结构的完整性。
3.4 迭代器
迭代器是访问集合元素的一种方式。迭代器从集合的第一个元素开始访问,直到所有的元素被访问完才结束。
3.4.1 可迭代对象
可迭代对象和迭代器是不同的概念。
python中,如果一个对象有iter() 和getitem()方法,则称这个对象为可迭代对象。
python中,用内置函数dir(),查看对象的属性、方法列表。
例如,打印出元组对象的属性和方法:
list_temp = ('a', 'b', 'c')
print(dir(list_temp))
输出:
'__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '_ getitem `', 'getnewargs', 'gt', 'hash', 'init', 'initsubclass', '` iter `', 'le', 'len', 'lt', 'mul', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'rmul', 'setattr', 'sizeof', 'str', 'subclasshook__', 'count', 'index'] `
列表、元组、字典、字符串等数据类型都是可迭代的(这里注意集合不是可迭代对象)
例如,打印出集合对象的属性和方法:
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
当然,自定义的类中只要实现了iter() 和getitem()方法,就也是可迭代的。
iter() :作用让对象可循环遍历
getitem():作用是可通过实例名[index]方式访问实例中的元素
3.4.2 迭代器的定义
在python中,如果一个对象有iter()和next()方法,则称这个对象时迭代器。
其中next()方法的作用是让对象可通过该next(实例名)访问下一个元素
列表、元组、字典、字符串等数据类型是可迭代的,但是都不是迭代器,因为都没有next()方法。
是不是迭代器,也可以通过python内置函数isinstance进行测试
例如:
from collections import Iterable
from collections import Iterator
# 列表、元组、字典、字符串都是可迭代的
print(isinstance([], Iterable))
print(isinstance((), Iterable))
print(isinstance({}, Iterable))
print(isinstance('', Iterable))
# 列表、元组、字典、字符串都不是迭代器
print('-----------------------')
print(isinstance([], Iterator))
print(isinstance((), Iterator))
print(isinstance({}, Iterator))
print(isinstance('', Iterator))
输出:
True
True
True
True
-----------------------
False
False
False
False
迭代器都是可迭代的,但可迭代的不一定是迭代器
迭代器和可迭代对象的区别:
可迭代对象中提前存储了所有的元素,而迭代器只有迭代到某个元素的时候,该元素才生成,迭代前可以不存在,迭代后可以销毁,因此,迭代器在处理大量数据或无限数据时,具有加载数据快,内存占用小的优点。
3.4.3 迭代器的创建
1、内建工厂函数
内建工厂函数iter返回一个迭代器,可以将可迭代对象转换为迭代器,例如:
a = [5, 6, 7, 8]
b = ('m', 'n', 'k')
c = 'hello'
print(iter(a))
print(iter(b))
print(iter(c))
d = iter(a)
print(next(d))
print(next(d))
print(next(d))
结果:
<list_iterator object at 0x000002BF937215F8>
<tuple_iterator object at 0x000002BF937215F8>
<str_iterator object at 0x000002BF937215F8>
5
6
7
还有自定义迭代器,用的不是太多,这里就不讲了,用到的时候再讲。
3.5 生成器
列表在创建的时候会将所有的元素全部创建好,再供用户使用,那如果你的元素有几十亿个,python就要在内存中开辟足够的空间存储,这就有可能导致内存不够的问题。如果只需要访问前面几个数据,那后面的绝大多数元素占用的空间就浪费了。
为了解决这种问题,python引入了生成器,根据事先设计好的规则开辟内存空间,创建对象供用户使用。
3.5.1 生成器的定义
生成器是一种特殊的迭代器,通过调用一个返回迭代器的函数yield来实现迭代操作。yeild相当于为函数封装了iter()和next()。
3.5.2 生成器的创建
1、使用列表推导式定义列表
与列表推导式类似,只不过是[]换成()
# 使用列表推导式定义列表
list_a = [x for x in range(10)]
print(list_a)
# 使用生成器推导式定义生成器
generator_b = (x for x in range(10))
print(generator_b)
print(next(generator_b))
print(next(generator_b))
print(next(generator_b))
print('---------------------')
for n in generator_b:
print(n)
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<generator object <genexpr> at 0x0000020D6D54ECA8>
1
2
---------------------
3
4
5
6
7
8
9
2、使用yeild关键字
如果一个函数的定义中包含yeild关键字,那这个函数就不再是一个简单的函数了,而是一个生成器。
举个例子,生成裴波那契数列的函数如下:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
fib(10)
输出:
1
1
2
3
5
8
13
21
34
55
如果将代码中的print(b)换成yeild(b),则这个fib函数就编程了生成器:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield (b)
a, b = b, a + b
n = n + 1
f = fib(10)
print(f)
for i in f:
print(i)
结果:
<generator object fib at 0x000001D01E7EECA8>
1
1
2
3
5
8
13
21
34
55
3.6 与条件语句、循环语句相关的内置函数
3.6.1 range函数
range的作用是返回一个可迭代对象,规则如下:
range([star,]end[,step])
其中star是初始位置,默认从0开始,end是结束位置,但不包含end,计算区间是[star,end),step是步长,step也可以为负数,反向遍历,range对象可用list转换成列表。
a = range(10)
print(a)
b = list(range(5))
print(b)
print(list(range(1, 8, 2)))
print(list(range(8, 1, -2)))
结果:
range(0, 10)
[0, 1, 2, 3, 4]
[1, 3, 5, 7]
[8, 6, 4, 2]
3.6.2 enumerate函数
enumerate函数返回的是一个enumerate对象,作用是枚举可迭代对象的每一个元素,将他们组成一个索引序列,可以同时获得索引和值。
a = list(range(9, 1, -2))
print(a)
b = enumerate(a)
print(b)
for index, value in b:
print(index, value)
结果:
[9, 7, 5, 3]
<enumerate object at 0x0000012DBA3EA168>
0 9
1 7
2 5
3 3
3.6.3 reversed函数
reversed作用是进行反向遍历,该函数可接收各种序列(元组、列表、字符串、区间等),然后返回一个反向的课迭代对象,需注意该函数对参数本身没有影响。
a = list(range(9, 1, -2))
print(a)
b = reversed(a)
print(b)
c = list(reversed(a))
print(c)
结果:、
[9, 7, 5, 3]
<list_reverseiterator object at 0x0000027DC50715F8>
[3, 5, 7, 9]
但是需要注意,如果第二次再使用reversed的,则会返回空置。
3.6.4 zip函数
zip函数将多个可迭代对象打包乘一个元组,返回个zip对象
list_1 = ['a', 'b', 'c']
list_2 = [1, 2, 3]
print(list(zip(list_1)))
print('----------------')
a = zip(list_1, list_2)
print(a)
print(list(a))
print('----------------')
for (x, y) in zip(list_1, list_2):
print(x, y)
结果:
[('a',), ('b',), ('c',)]
----------------
<zip object at 0x00000203CB83EFC8>
[('a', 1), ('b', 2), ('c', 3)]
----------------
a 1
b 2
c 3
3.6.5 *zip函数
*zip是zip函数的反过程,将zip对象还原为组合前的数据
list_1 = ['a', 'b', 'c']
list_2 = [1, 2, 3]
a = zip(list_1, list_2)
print(a)
print(list(a))
c, d = zip(*zip(list_1, list_2))
print(c)
print(d)
结果:
<zip object at 0x000002B27646DD48>
[('a', 1), ('b', 2), ('c', 3)]
('a', 'b', 'c')
(1, 2, 3)
3.6.6 sorted函数
sorted函数可以对所有的可迭代对象进行排序,返回的是一个新的可迭代对象,而不是在原来的基础上进行操作。
list_1 = ['c', 'b', 'a']
print(list_1)
print(id(list_1))
b = sorted(list_1)
print(id(b))
print(b)
结果:
['c', 'b', 'a']
3044259629704
3044276555912
['a', 'b', 'c']
需注意sort和sorted的区别,sort主要用于列表,而sorted对所有课迭代对象都起作用。
3.7 总结
本章介绍了python中的选择结构和循环结构,又介绍了迭代器和生成器,最后介绍了一些python的内置函数。