Python程序流程控制

Python程序流程控制

一、if分支结构

1.1 基本结构

if x>y:
    a=x
elif x==y:
    a=0
else:
    a=-x

如c/c++一样,可以有多个elif分支,else可以省略,注意作用范围由缩进对齐控制

1.2 真值测试

非0即真

0、空对象(空列表[],空字典{})、None都为假

其他与c/c++类似

特别说明下not、and、or运算符,分别是非、与、或运算,与C/C++类似

and和or运算符是由左向右运算的,称之为短路计算

and遇到第一个假,返回,若直到最后一个都是真,则返回最后一个

or遇到第一个真,返回,若直到最后一个都是假,则返回最后一个

>>> 0 and 2
0
>>> [] and 2
[]
>>> {} and 2
{}
>>> 2 and 5
5
>>> 5 and 2
2

or类似

1.3 if ...else 三元表达式


>>> x=1
>>> y=2
>>> if x>y:
...     a=x
... else:
...     a=y
...
>>> a
2

如上语句可以简化为if...else三元表达式

a=x if x>y else y

Python还支持从列表中挑选对象,格式如下


a=[x,y][f]

f为假时,将x赋给a,否则将y赋值给a

不过上述语句只是一种用法的特例,即f可以是索引,f为假等效于f=0,f为真等效于f=1,如下


>>> a=[1,2,3,4,5,6][5]
>>> a
6
>>> a=[1,2,3,4,5,6][0]
>>> a
1

二、for循环

2.1 基本格式


for var in object:
  循环体语句块
else:
  语句块

else部分可以省略。for执行时,依次将可迭代对象object中的值赋值给变量var。var每赋值一次,则执行一次循环体语句块。循环结束时,若有else部分,则执行。else部分只在正常结束循环时执行。如果break跳出循环,则不执行else部分。

>>> for x in (1,2,3,(4,5)):
...   print(x)
...
1
2
3
(4, 5)
>>> for x in 'book':
...   print(x)
...
b
o
o
k
>>> for x in (1,2,3):
...   print(x*2)
... else:
...   print('loop over')
...
2
4
6
loop over

在迭代字典对象时,变量依次迭代字典的各个键。迭代字典时,x分别为各个对的key

>>> d={'name':'John','age':25}
>>> for x in d:print(x,d[x])#注意字典无序,打印结果可能不一样
...
name John
age 25
>>>

可以用range()函数来生成包含连续多个整数的range对象,基本格式如下


range(end)
range(start,end[,step])

如下:


>>> for x in range(3):print(x)
...
0
1
2
>>> for x in range(-2,2):print(x)
...
-2
-1
0
1
>>> for x in range(-2,2,2):print(x)
...
-2
0

2.2 多个变量迭代

循环时可使用多个变量来迭代序列对象

>>> for(a,b) in ((1,2),(3,4),(5,6)): print(a,b)
...
1 2
3 4
5 6
>>>

与赋值语句类似,可以用"*"给变量赋值一个列表。例如:


>>> for(a,*b) in ((1,2,'abc'),(3,4,5)): print(a,b)
...
1 [2, 'abc']
3 [4, 5]
>>>

2.3 break和continue

break和continue用法与C/C++类似,不同的是break跳出循环时,循环else部分不执行,如下找回文数例子程序:


>>> a=[]
>>> n=0
>>> for x in range(100,999):
...   s=str(x)
...   if s[0]!=s[-1]:continue
...   a.append(x)
...   n+=1
...   if n==10:break
... else:
...   print('loop over')
...
>>> print(a)
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
>>>

2.3 嵌套使用for循环

和C/C++类似,如下:

>>> for x in range(4,100):
...    for n in range(2,x):
...      if x%n==0:
...       break
...    else:
...      print(x,end=' ')
... else:
...    print('over')
...
5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 over
>>>

顺便提一下,不同循环的对齐,空格数可以不一样,如上,用了3个,2个,1个来对齐不同语句块。

三、while循环

和C/C++类似,但有else部分,如python的for循环,break和continue也和for类似,嵌套用法也和for类似


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

如:


>>> a=1
>>> while a<10:
...   b=1
...   while b<=a:
...     print('%d*%d=%2d '%(a,b,a*b),end=' ')
...     b+=1
...   print()
...   a+=1
...
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
>>>

生成10个两位的随机素数

>>> while n<10:
...   x=random.randint(10,99)
...   a=2
...   while a<x-1:
...     if x%a==0:break
...     a+=1
...   else:
...     print(x,end=' ')
...     n+=1
...
73 79 61 53 13 29 59 61 19 79 >>>

四、迭代和列表解析

4.1 迭代

python中的各种序列(字符串、列表、元组、字典以及文件)均是可迭代对象。可迭代对象可以使用迭代器来遍历包含的元素。

字符串、列表、元组以及字典等对象虽然是可迭代对象,但他们没有自己的迭代器。Python使用iter()函数来生成可迭代对象的迭代器,然后使用迭代器调用next()函数来遍历对象。next()函数依次返回可迭代对象的一个元素,无元素时,返回一个StopIteration异常。如:


>>> d=iter([1,2,3])
>>> next(d)
1
>>> next(d)
2
>>> next(d)
3
>>> next(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
>>> d=iter((1,2,(3,4)))
>>> next(d)
1
>>> next(d)
2
>>> next(d)
(3, 4)
>>>
>>> d=iter('abc')
>>> next(d)
'a'
>>> next(d)
'b'
>>> next(d)
'c'
>>>
>>> d=iter({'name':'John','age':25})
>>> next(d)
'name'
>>> next(d)
'age'
>>> next(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> d=iter({'name':'John','age':25}.keys())
>>> next(d)
'name'
>>> next(d)
'age'
>>> d=iter({'name':'John','age':25}.values())
>>> next(d)
'John'
>>> next(d)
25
>>> d=iter({'name':'John','age':25}.items())
>>> next(d)
('name', 'John')
>>> next(d)
('age', 25)
>>>

文件对象有自己的迭代器:__next__()方法。如


>>> mf=open(r'C:\Users\wjt\Desktop\test.txt')
>>> mf.__next__()
'abc\n'
>>> mf.__next__()
'123\n'
>>> mf.__next__()
'hello python'
>>> mf.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

也可以使用next()函数来调用文件对象的迭代器。注意,不用使用iter来生成迭代器。如:

>>> mf=open(r'C:\Users\wjt\Desktop\test.txt')
>>> next(mf)
'abc\n'
>>> next(mf)
'123\n'
>>> next(mf)
'hello python'
>>> next(mf)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

注意可以使用dir()函数查找对象或者类型的可用方法,若有__next__()方法,说明该类型的对象拥有自己的迭代器,可直接调用next()来执行迭代操作。

>>> mf=open(r'C:\Users\wjt\Desktop\test.txt')
>>> dir(mf)
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '_
_doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattrib
ute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__rep
r__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed'
, '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer',
 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty',
 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', '
readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writel
ines']
>>> type(mf)#查看mf的类型,实例和类查出来,函数竟然不一样。。。不知道为什么。
<class '_io.TextIOWrapper'>
 >>> dir('_io.TextIOWrapper')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '_
_eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs
__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__'
, '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__r
epr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subcl
asshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', '
expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isd
ecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'issp
ace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'pa
rtition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip
', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate
', 'upper', 'zfill']
>>> dir('file')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '_
_eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs
__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__'
, '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__r
epr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subcl
asshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', '
expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isd
ecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'issp
ace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'pa
rtition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip
', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate
', 'upper', 'zfill']
>>>

4.2 列表解析

列表解析与循环的概念紧密相关下面是用for循环修改列表和使用列表解析来代替循环的例子:

>>> t=[1,2,3,4]
>>> for x in range(len(t)):
...   t[x]=t[x]+10
...
>>> t
[11, 12, 13, 14]
>>>
>>>
>>> t=[1,2,3,4]
>>> t=[x+10 for x in t]
>>> t
[11, 12, 13, 14]
>>>

可以看出列表解析使用很短的代码实现了相同目的,而且代码运行也会更快。列表解析结构不仅仅适用于列表,也可用于多种场合。

4.2.1 带条件的列表解析

在列表解析结构末尾使用if头部来执行筛选。如:


>>>[x+10 for x in range(10) if x%2==0]
[10, 12, 14, 16, 18]

4.2.2 多重解析嵌套

与for循环类似,在列表解析中也可在for部分进行嵌套。例如:


>>> [x+y for x in (10, 20) for y in (1,2,3)]
[11, 12, 13, 21, 22, 23]

用循环实现


>>> a=[]
>>> for x in (10,20):
...   for y in (1,2,3):
...     a.append(x+y)
...
>>> a
[11, 12, 13, 21, 22, 23]
>>>

嵌套解析还可以分别使用if执行筛选


>>> [x+y for x in (5,10,20) if x>10 for y in (1,2,3) if y%2==1]
[21, 23]

4.2.3 列表解析用于元组

元组也可以应用列表解析


>>> (x for x in range(10))
<generator object <genexpr> at 0x00000000011BED58>
>>> tuple(x for x in range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> tuple(x*2 for x in range(5))
(0, 2, 4, 6, 8)
>>> tuple(x*2 for x in range(10) if x%2==1)
(2, 6, 10, 14, 18)

4.2.4 列表解析用于集合


>>> {x for x in range(10)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> {x for x in range(10) if x%2==1}
{1, 3, 5, 9, 7}

4.2.5 列表解析用于字典

>>> {x:ord(x) for x in 'abcd'}#ord()为将字符转成ascii码
{'c': 99, 'd': 100, 'a': 97, 'b': 98}
>>> {x:ord(x) for x in 'abcd' if ord(x)%2==0}
{'d': 100, 'b': 98}

4.2.6 列表解析用于文件

列表解析用于文件时,每次从文件读取一行数据


>>> [x for x in open(r'C:\Users\wjt\Desktop\test.txt')]
['abc\n', '123\n', 'hello python']
>>> [x.strip() for x in open(r'C:\Users\wjt\Desktop\test.txt')]#strip()表示不显示后面的不可显示字符
['abc', '123', 'hello python']
>>> [x.strip() for x in open(r'C:\Users\wjt\Desktop\test.txt') if x[0]=='1']
['123']

test.txt文件内容如下

abc123hello python

4.2.7 其他的列表解析应用

一些函数中可直接使用可迭代对象,如

>>> all([0,2,4,1,3,5])
False
>>> any([0,2,4,1,3,5])
True
>>> sum([0,2,4,1,3,5])
15
>>> sorted([0,2,4,1,3,5])
[0, 1, 2, 3, 4, 5]
>>> min([0,2,4,1,3,5])
0
>>> max([0,2,4,1,3,5])
5
>>> min(open(r'C:\Users\wjt\Desktop\test.txt'))
'123\n'
>>> max(open(r'C:\Users\wjt\Desktop\test.txt'))
'hello python'
>>> list(open(r'C:\Users\wjt\Desktop\test.txt'))
['abc\n', '123\n', 'hello python']
>>> set(open(r'C:\Users\wjt\Desktop\test.txt'))
{'abc\n', '123\n', 'hello python'}
>>> tuple(open(r'C:\Users\wjt\Desktop\test.txt'))
('abc\n', '123\n', 'hello python')
>>> a,b,c=open(r'C:\Users\wjt\Desktop\test.txt')
>>> a,b,c
('abc\n', '123\n', 'hello python')
>>> a
'abc\n'
>>> a,*b=open(r'C:\Users\wjt\Desktop\test.txt')
>>> a,b
('abc\n', ['123\n', 'hello python'])
>>>

4.3 zip、map和filter

zip、map和filter函数生成的可迭代对象均有自己的迭代器,可使用next函数执行迭代操作。

4.3.1 zip函数

zip函数参数为多个可迭代对象,每次从每个可迭代对象中取一个值组成一个元组,直到可迭代对象中的值取完,生成的zip对象包含了对象包含了一系列的元组。例如:


>>> x=zip((1,2,3),(10,20,30))
>>> x
<zip object at 0x0000000001597C08>
>>> next(x)
(1, 10)
>>> next(x)
(2, 20)
>>> next(x)
(3, 30)
>>> next(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> x=zip('abc',(1,2,3))
>>> next(x)
('a', 1)
>>> next(x)
('b', 2)
>>> next(x)
('c', 3)
>>> x=zip((1,2),'ab',[5,6])
>>> next(x)
(1, 'a', 5)
>>> next(x)
(2, 'b', 6)
>>> x=zip((1,2),'xyz')
>>> next(x)
(1, 'x')
>>> next(x)
(2, 'y')
>>> next(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

4.3.2 map函数

map函数用于将函数映射到可迭代对象,对可迭代对象中的每个元素应用该函数,函数返回值包含在生成的map对象中。例如:


>>> x=map(ord,'abc')
>>> x
<map object at 0x00000000011DBBE0>
>>> next(x)
97
>>> next(x)
98
>>> next(x)
99
>>> list(x)
[]
>>> list(map(ord,'abc'))
[97, 98, 99]

4.3.3 filter函数

filter函数与map函数有点类似,filter函数用指定函数处理可迭代对象。若函数返回值为真,则对应可迭代对象元素包含在生成的filter对象序列中。

例如,下面的代码筛选出可转换为真的对象。


>>> x=filter(bool,(1,0,-1,2,'ab',(),[],{},(1,2),[1,2],{1,2},{'a':1}))
>>> next(x)
1
>>> next(x)
-1
>>> list(x)
[2, 'ab', (1, 2), [1, 2], {1, 2}, {'a': 1}]

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值