Python基础4: 判断与循环
四. 控制流(判断和循环)
控制流是编程中重要的部分, 尤其在面向过程编程中十分重要. 各种编程语言的控制流大同小异, python的控制流十分简单, 有其余编程基础的只需看两眼语法即可.
4.1 if...elif...else... 条件语句
条件判断语句用于控制程序的走向, 就像交叉路口一样, 不同条件下程序走不同的路径. 条件判断语句是使得程序具有 类似人的"判断" 能力的核心.
- 条件判断语句使用
if
来指明判断条件, 随后跟:
, 接上缩进的语句块指明该条件下的行为. -
else
语句是和if
相对应的, 当前面的if
均不发生时else后语句块内容 -
elif
是上面条件不成立的话,满足后面条件将执行后续语句块. 相当于else if
- 判断语句的语句块中支持嵌套, 就是多层判断或循环. 注意缩进.
### if elif else
if condition1:
statement1
elif condition2:
statement2
else:
statement3
### 嵌套
if condition1:
statement1
if condition2:
statement2
else:
statement3
else:
statement4
- 如果较简单可以写在一行:
if condition: statement
- python里面没有
case
,switch
一类的选择语句, 可以通过if
来完成.
条件表达式
条件表达式是根据表达式的结果, 有条件地进行赋值. 例如:
# if语句
if a<b:
minvalue=a
else:
minvalue=b
# 条件表达式
minvalue=a if a<b else b
在列表推导式里面常用条件表达式:
有两类形式:
- 赋值在最前面,
if
在for
后面,不带else
分支, 仅起到条件限定过滤的作用. 支持多层条件. - 带
else
形式和一般条件表达式一样, 写在for
前面.
[ x*x for x in range(10) if x%2==0 ]
## [0, 4, 16, 36, 64]
[ x*x for x in range(10) if x%2==0 if x>5 ]
## [36, 64]
[ x*x if x%2==0 else x**3 for x in range(10) ]
## [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]
4.2 for 循环
循环是编程里极为常用和重要的部分, 通过循环可以反复进行操作, 帮助人从繁琐工作中脱身. python支持for
循环和while
循环, 没有别的语言里的像goto
, do
等循环.
循环条件是判断循环是否继续执行的部分. 无论for还是while循环都有这部分. for循环使用的是成员检查in
的条件, 当循环变量属于范围时, 则继续进行循环的结构部分.
对于循环条件:
-
in
前面是循环变量,随着循环进行而自动改变, 实际是每次调用后面的可迭代对象的next()
方法,导致循环变量的改变. -
in
后面一般是可迭代对象, 例如列表, 数组, 字典(迭代key), 文件对象等. 要用数字控制,一般使用range()
函数制造循环使用的数列. -
for
循环属于有限循环, 根据迭代对象的内容进行循环; 这和while
循环使用指定条件控制循环不同, 条件一直为真循环则一直进行, 可以进行无限循环, 也可以在事先不清楚循环进行次数时执行循环, 直到一定条件才停止 - 循环变量实际是每次进行循环均执行一次
i=iterobj.next()
, 其值由迭代器的产出决定, 该迭代器在循环进行前产生. 这有几个注意项:- 循环变量不受循环内改变, 因为每次循环都会对循环变量重新赋值. 这一定和C++不同, 后者会受循环变量的变化而变化.
- 尽管循环的迭代器在循环开始时生成, 但如果改变循环的可迭代对象, 会影响循环的进行. 因为迭代器会记住迭代的步, 即运行到可迭代对象什么位置, 但改变可迭代对象的内容, 就会影响循环.
- 循环变量的作用域并非循环内私有, 如果循环之前也定义了该变量, 则会根据循环重新定义. 循环结束后循环变量的值依然保留最后一个值. 循环变量的值还常被用在嵌套的循环内.
- for循环变量的赋值支持解包操作, 如
for x,y in dictA.items()
, 即同时对几个变量赋值, 但要注意被迭代的对象内的结构要和解包一致.
-
for
循环也支持else:
子句, 就是接一个不满足条件跳出循环时的执行动作. 注意,else
是在循环条件不满足时才执行, 一般循环完成时会执行一次. 有一种例外: 使用break
跳出循环时, 并没有再进行循环条件的判断, 因此不会进行else
子句.
在对序列进行
for in
时,尽量不要对该序列进行删增,排序等操作,易错(可能干扰迭代器)!最好先用一个替代序列seq2=seq1[:]
来赋值进行操作。注意后面的例子.
对于循环内容:
- 循环将进行
for
后:
的紧跟语句块, 每次循环将执行后面的语句块 - 循环的语句块支持嵌套, 即循环内再嵌套循环, 嵌套的循环执行完后, 相当于上一层循环的一次执行.
- 循环语句块支持
break
,continue
语句,控制循环的进行:-
break
是跳出循环, 注意是跳出当前语句块所在循环, 并不跳出上级的循环. 会跳过for的else
子句. -
continue
是跳过语句块后面的部分, 执行下一次循环. 即中断当前循环执行下一次循环
-
# for 循环一般形式
for i in iterableObj:
statement;
# 可迭代对象例如: list/tuple/set/string
for i in iterobj:
##### 判断是否可迭代对象:
from collections import Iterable
isinstance(obj, Iterable);
# 嵌套循环(可嵌套for或while循环):
for i in range(1,100,10):
## 1 11 21 ... 91
for j in range(10):
## 0 1 2 ... 9
print i+j
## 1 2 3 ... 100
# 使用else子句, 注意break的情况
for i in range(1,100,input("Enter an Interval:\n")):
if i % 17 == 0:
print "Number",i," found! Break!"
break
else:
print "Can't find number!"
## 输入3: Number 34 found! Break!
## 输入13: Can't find number!
# for循环变量不被循环过程所改变
for i in range(10):
i+=2
print i
## 2 3 ... 10 11
# 改变可迭代对象会影响循环:
k=range(10)
j=0
for i in k:
k[j+1]=k[j+1]**2
k.append(k[j+1])
j+=1
print i
## 0 1 4 9 16 25 36 49 64 81 1 16 81 256 625 1296 2401 4096 6561 1 256 6561 ...
### 在该循环中, 既改变了迭代对象列表k的每项的值, 同时还不停增长k的长度, 因此该循环导致死循环.
# 使用创建的数列来控制循环
for i in range(start, end, step):
# 经常会使用计数来记录循环运行次数或作索引
n=0
for i in range(1,100,3):
print "Index %d is %d;" % (n,i),
n+=1
## Index 0 is 1; Index 1 is 4; ... Index 31 is 94; Index 32 is 97;
# 对于列表, 循环数值同时亦可以记录对应索引值,可以使用 enumerate函数 (会进行解包)
### 上述例子可以改为:
for index, value in enumerate(range(1,100,3)):
print "Index %d is %d;" % (index,value),
# 利用zip来合并序列的项, 并解包
for x, y in zip([1,2,3,4],'hello'):
print y,x,
## h 1 e 2 l 3 l 4
# 对于字典, 循环控制比较特殊
### 循环字典的键:
for key in dict:
### 循环字典的值
for val in dict.values():
### 同时循环字典的键和值
for key,val in dict.items():
# 可以对于文件对象, 逐行读出文件内容:
f=open('filename')
for line in f:
print line
相关函数学习
除了上面数据结构中提及的range
, xrange
, reversed
, sorted
用于产生列表或者迭代器外, 这些可以用作for的可迭代对象, 除此以外, 还有以下相关的:
-
enumerate(iterable [, start=0])
: 产生一个可迭代的enumerate
对象,
该对象可以逐一产生元组(0,seq[0]), (1,seq[1]) .... 即可迭代对象和其索引号, 索引号默认start是0开始,可以自己定义. -
zip(seq1, [seq2 ,seq3 ....])
: 将给定序列的相同索引的项合并为元组, 将所有索引的合并元组作为列表返回. 如果序列长度不一致, 以短的序列的长度为准. 注意python2该方法可能返回一个很耗内存的大列表, 而python3则是迭代器. python2可以使用itertools.izip()
来返回迭代器.
4.3 while循环
while
循环是自定义条件的循环, 格式是while 条件: 语句块
, 只要条件返回True
,就执行后面的语句块.
- while循环因为可以定义循环条件, 所以循环可以根据情况进行, 从而实现不确定次数的循环, 甚至可以一直进行循环.
- 支持嵌套循环,
for
/while
各种嵌套. - 支持
break
和continue
的使用 - while还支持
else
子句 (不满足循环条件时执行一次),break
时不执行else字句 -
while True: break
也是常用的, 条件直接True就会一直循环, 而打断循环则利用语句块内的break
实现, 一般结合if
来使用.
while condition:
statement;
[else:]
[statement;]
while True:
statement1
if condition:
statement2
break
在别的语言里面, 循环还有do until/while
和goto
语句可以用于循环, 但python并不支持. 可以用while
循环来实现(goto
比较特殊, 由于容易出错一般避免使用)
4.4 break, continue, exit
这三个关键词(exit是函数) 主要是控制循环的执行, 在一定情况下跳出循环或跳过后续, 一般和条件判断语句结合使用.
-
break
: 打断整个循环并跳出. 不执行else
子句. -
continue
: 跳过该次循环的后面部分, 开始下次循环. -
exit()
: 结束脚本运行, 出错时再用.
另外也有一个单词的独立语句:
-
pass
: 这个为空语句, 什么都不执行, 纯粹只是为了满足语法要求不出错而存在的空语句, 有时也作为临时占位, 待后续再补充相应代码.