天天看点

Python程序设计 | Python流程控制语句

程序有三种基本的控制结构:顺序结构、选择结构、循环结构。

顺序结构:

Python程序设计 | Python流程控制语句

选择结构(分支结构):

Python程序设计 | Python流程控制语句

循环结构:

Python程序设计 | Python流程控制语句

3.1 条件语句

条件语句是通过判断条件是否成立,根据条件表达式的结果做出决策,控制不同代码块的执行。

3.1.1 条件表达式

条件表达式由运算符和操作数组成

例如:a<4,其中a、4都是操作数,小于符号<是运算符

判断条件可以是具有布尔属性的任意元素,包括数据、变量或由变量与运算符组成的表达式,若其布尔属性为True,条件成立;若布尔属性为False,条件不成立。

除了非空常量外,Python还常使用关系操作符和成员运算符构成判断条件 。

条件表达式常用的运算符有:

算术运算符:+、-、*、/、//、%、**

关系运算符:

Python程序设计 | 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 单分支选择结构

Python程序设计 | Python流程控制语句
  • 若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 双分支选择结构

Python程序设计 | Python流程控制语句
  • 若if语句中的判断条件成立,执行代码段1
  • 若判断条件不成立,则执行代码段2

示例:使用二分支结构判断当天是否是工作日。

day = int(input("今天是工作日吗(请输入整数1~7)?"))

if day in [1,2,3,4,5]:

print("今天是工作日。")

else:

print("今天非工作日。")

3.1.4 多分支选择结构

Python程序设计 | Python流程控制语句

3.1.5 选择结构的嵌套

选择结构的嵌套是指选择结构的内部包含选择结构

Python程序设计 | Python流程控制语句
Python程序设计 | Python流程控制语句

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循环

Python程序设计 | Python流程控制语句
  • 若循环条件为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 循环

Python程序设计 | Python流程控制语句
  • 目标可以是字符串、文件、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语句

Python程序设计 | Python流程控制语句
Python程序设计 | Python流程控制语句

3.3.2 continue语句

Python程序设计 | Python流程控制语句
Python程序设计 | Python流程控制语句

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的内置函数。