[PYTHON] 核心编程笔记之八-Python条件和循环
8.1 if语句
if expression:
expr_true_suite
8.1.1 多重条件表达式
单个if 语句可以通过使用and,or和not实现多重判断条件或是否定判断条件
if not warn and (system_load>=10):
print "WARNING: losing resources"
warn +=1
8.1.2 单一语句的代码块
if make_hard_copy: send_data_to_printer()
8.2 else 语句
if expression:
expr_true_suite
else:
expr_false_suite
8.2.1 避免"悬挂else"
8.3 elif(即else-if)语句
if expression1:
expr1_true_suite
elif expression2:
expr2_true_suite
elif expressionN:
expeN_true_suite
else:
none_of_the_above_suite
8.4 条件表达式(即"三元操作符")
>>> x, y=4, 3
>>> if x < y:
... smaller = x
... else:
... smaller = y
...
>>> smaller
3
>>> smaller = (x < y and [x] or [y])[0]
>>> smaller
3
>>> smaller = x if x < y else y
>>> smaller
3
8.5 while 语句
8.5.1 一般语法
while 循环的语法如下:
while expression:
suite_to_repeat
while循环的suite_to_repeat子句会一直循环下去,直到expression值为假
8.5.2 技术循环
>>> count = 0
>>> while (count < 9):
... print 'the index is:',count
... count +=1
...
the index is: 0
the index is: 1
the index is: 2
the index is: 3
the index is: 4
the index is: 5
the index is: 6
the index is: 7
the index is: 8
8.5.3 无限循环
while True:
handle,indata = wait_for_client_connect()
outdata = process_request(indata)
ack_result_to_client(handle,outdata)
注: 以上代码为无限循环,因为服务器代码是用来等待客户端(可能通过网络)来连接的,这些客户端向服务器发送请求,服务器处理请求,请求被处理,服务器向客户端返回数据
8.6 for 语句
8.6.1 一般语法:
for iter_var in iterable:
suite_to_repeat
每次循环,lter_var迭代变量被设置为可迭代对象的当前元素,提供给suite_to_repeat语句块使用
8.6.2 用于序列类型
>>> for eachLetter in 'Names':
... print 'current letters',eachLetter
...
current letters N
current letters a
current letters m
current letters e
current letters s
通过序列项迭代
>>> nameList = ['Walter',"Nicole",'Steven','Henry']
>>> for eachName in nameList:
... print eachName,"Lim"
...
Walter Lim
Nicole Lim
Steven Lim
Henry Lim
通过序列索引迭代
>>> nameList = ['Cathy',"Terry","Joe",'heather','Lucy']
>>> for nameIndex in range(len(nameList)):
... print "Liu",nameList[nameIndex]
...
Liu Cathy
Liu Terry
Liu Joe
Liu heather
Liu Lucy
>>> len(nameList)
5
>>> range(len(nameList))
[0, 1, 2, 3, 4]
使用range()我们可以得到用来迭代nameList的索引数列表:使用切片/下标操作符([]),就可以访问对应的序列对象
使用项和索引迭代
使用enumerate()函数
>>> nameList = ['Donn','Shirley','Ben','Janice','David','Yen','Wendy']
>>> for i,eachLee in enumerate(nameList):
... print "%d %s Lee" %(i+1,eachLee)
...
1 Donn Lee
2 Shirley Lee
3 Ben Lee
4 Janice Lee
5 David Lee
6 Yen Lee
7 Wendy Lee
8.6.3 用于迭代器类型
用for循环访问迭代器和访问序列的方法差不多,区别是for语句会做一些额外的事情
迭代器对象有一个next()方法,调用后返回下一条目,所有条目迭代完,迭代器引发一个StopIteration一场告诉程序循环结束,for语句在内部调用next()病捕获异常
8.6.4 range()内建函数:
range(start, end, step = 1)
range()会返回一个包含所有k的列表,这里start<=k<end, 从start到end, k每次递增step, step不可以为零,否则将发生错误
>>> range(2,19,3)
[2, 5, 8, 11, 14, 17]
只给定两个参数,省略step,step就使用默认1
>>> range(3,7)
[3, 4, 5, 6]
例:
>>> for eachVal in range(2,19,3):
... print "value is: ",eachVal
...
value is: 2
value is: 5
value is: 8
value is: 11
value is: 14
value is: 17
range()简略语法:
range(end)
range(start,end)
>>> range(5)
[0, 1, 2, 3, 4]
>>> for count in range(2,5):
... print count
...
2
3
4
注:
>>> range(start=0,end,step=1)
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
这个语法不可以使用两个参数调用,因为step要求给定start
8.6.5 xrange()内建函数:
8.6.6 与序列相关的内建函数:
sorted(),reversed(),enumerate(),zip()
>>> albums = ('Poe','Gaudi','Freud','Poe2')
>>> years = (1976,1987,1990,2003)
>>> for album in sorted(albums):
... print album,
...
Freud Gaudi Poe Poe2
>>> for album in reversed(albums):
... print album,
...
Poe2 Freud Gaudi Poe
>>> for i,album in enumerate(albums):
... print i,album
...
0 Poe
1 Gaudi
2 Freud
3 Poe2
>>> for album,yr in zip(albums,years):
... print yr, album
...
1976 Poe
1987 Gaudi
1990 Freud
2003 Poe2
8.7 break语句
break语句可以结束当前循环然后跳转到下条语句,常用于while和for循环
count = num / 2
while count > 0:
if num % count == 0:
print count, 'is the largest factor of', num
break
count -= 1
8.8 continue 语句
continue在开始下一次循环前需要满足一些先决条件,否则循环会正常结束,常用在while和for循环里
#!/usr/bin/env python
valid = False
count = 3
while count > 0:
input = raw_input("enter password")
for eachPasswd in passwdList:
if input == eachPasswd:
valid = True
break
if not valid:
print "invalid input"
count -= 1
continue
else:
break
8.9 pass语句
def foo_func():
pass
或是
if user_choice = 'do_calc':
pass else:
pass
这样的代码结构在开发和调试时很有用,因为编写代码的时候你可能要先把结构定下来,但你不希望它干扰其他已经完成的代码,在不需要它做任何事情的地方,放一个pass将是一个很好的主意
8.10 再谈else语句
Python可以在while和for循环中使用else语句,在循环使用时,else子句只在循环完成后执行,也就是break会跳过else块
例:
-------------------------
#!/usr/bin/env python
def showMaxFactor(num):
count = num / 2
while count > 1:
if num % count ==0:
print 'largest factor of %d is %d' %(num,count)
break
count -= 1
else:
print num, "is prime"
for eachNum in range(10,21):
showMaxFactor(eachNum)
--------------------------
showMaxFactor()函数中第3行的循环从amount的一般开始计数(这样就可以检查这个数是否能被2整除,如果可以,那就找到了最大约数),然后循环每次递减1,直到发现约数,如果循环递减到1还没有找到约束,那么这个数一定是素数,11-12行的else子句负责处理这样的情况
largest factor of 10 is 5
11 is prime
largest factor of 12 is 6
13 is prime
largest factor of 14 is 7
largest factor of 15 is 5
largest factor of 16 is 8
17 is prime
largest factor of 18 is 9
19 is prime
largest factor of 20 is 10
for与while处理方式相同,只要for循环为正常结束,else子句就会执行
条件与循环语句对照表
ifwhilefor
elif*
else***
break**
continue**
pass***
8.11 迭代器和iter()函数:
8.11.1 什么是迭代器?
8.11.2 为什么要迭代器?
8.11.3 如何迭代?
next() reversed() enumerate() any() all()方法
8.11.4 使用迭代器
例:
>>> myTuple = (123, 'xyz', 45,67)
>>> i = iter(myTuple)
>>> i.next()
123
>>> i.next()
'xyz'
>>> i.next()
45
>>> i.next()
67
>>> i.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
如果这是一个实际应用程序,那么我们需要把代码放在一个try-except块中,序列现在会自动的产生他们自己的迭代器,所以一个for循环:
for i in seq:
do_something_to(i)
------------------------------
fetch = iter(seq)
while True:
try:
i = fetch.next()
except StopIteration:
break
do_something_to(i)
字典
语句for eachKey in myDict.keys()可以缩写为for eachKey in myDict
>>> legends = {('Poe', 'author'):(1809, 1849, 1976),('Gaudi','architect'):(1852,1906,1987),('Freud','psychoanalyst'):(1856,1939,1990)}
>>> for eachLegend in legends:
... print 'Name: %s \t Occupation: %s' % eachLegend
... print 'Birth:%s\tDeath: %s\tAlbum: %s\n' %legends[eachLegend]
...
Name: Poe Occupation: author
Birth:1809 Death: 1849 Album: 1976
Name: Gaudi Occupation: architect
Birth:1852 Death: 1906 Album: 1987
Name: Freud Occupation: psychoanalyst
Birth:1856 Death: 1939 Album: 1990
Name: Poe Occupation: author
Birth:1809 Death: 1849 Album: 1976
Name: Gaudi Occupation: architect
Birth:1852 Death: 1906 Album: 1987
Name: Freud Occupation: psychoanalyst
Birth:1856 Death: 1939 Album: 1990
另外:python还引进了三个新的内建字典方法来定义迭代:myDict.iterkeys() (通过keys迭代),myDict.itervalues() (通过values迭代),以及myDict.iteritems() (通过key/value对来迭代)
文件
文件对象生成的迭代器会自动调用readline()方法
for eachLine in myFile.readlines(): 可以简化为 for eachLine in myFile:
例:
--------------------------------
>>> myFile = open('test20.py')
>>> for eachLine in myFile:
... print eachLine,
...
#!/usr/bin/env python
while True:
try:
usr_input_1 = int(raw_input("please input the first word: ").strip())
usr_input_2 = int(raw_input("please input the second word: ").strip())
usr_input_3 = int(raw_input("please input the third word: ").strip())
break
except:
print "please input the number!"
list = [usr_input_1,usr_input_2,usr_input_3]
average = sum(list)/len(list)
print "The list is %s" %list
print "The average of the list is %i" %average
>>> myFile.close()
--------------------------------------------------
8.11.5 可变对象和迭代器
循环列表的时候删除满足(或不满足)特定条件的项:
for eachURL in allURLs:
if not eachURL startswith('http://'):
allURLs.remove(eachURL)
在迭代字典key时,绝不能改变字典,否则不会继续执行下去:
>>> myFile.close()
>>> myDict = {'a':1,'b':2,'c':3,'d':4}
>>> for eachKey in myDict:
... print eachKey,myDict[eachKey]
... del myDict[eachKey]
...
a 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
8.11.6 如何创建迭代器
iter(obj)检查传递的是不是序列,如果是,根据索引从0一直迭代到结束
iter(fuc,sentinel)重复调用func,直到迭代器的下个值等于sentinel
8.12 列表解析
语法:
[expr for iter_var in iterable]
for循环迭代iterable对象的所有条目,前边的expr应用于序列的每个成员,最后的结果值是该表达式产生的列表
例:
计算序列成员的平方的lambda函数表达式
>>> map(lambda x: x**2,range(6))
[0, 1, 4, 9, 16, 25]
列表解析方法:
>>> [x ** 2 for x in range(6)]
[0, 1, 4, 9, 16, 25]
结合if语句,列表解析还提供一个扩展版本的语法:
[expr for iter_var in iterable if cond_expr]
使用filter()和lambda挑出序列的奇数:
>>> seq = [11,10,9,9,10,10,9,8,23,9,7,18,12,11,12]
>>> filter(lambda x: x % 2,seq)
[11, 9, 9, 9, 23, 9, 7, 11]
使用列表解析:
>>> [x for x in seq if x % 2]
[11, 9, 9, 9, 23, 9, 7, 11]
矩阵样例:
迭代一个有三行五列的矩阵
>>> [(x+1,y+1) for x in range(3) for y in range(5)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]
磁盘文件样例:
计算出一个数据文件所有非空白字符的数目:
>>> f = open('test20.py','r')
>>> len([word for line in f for word in line.split()])
57
快速计算文件大小
>>> import os
>>> os.stat('test20.py').st_size
497
>>> f.seek(0)
>>> sum([len(word) for line in f for word in line.split()])
391
8.13 生成器表达式
列表解析:
[expr for iter_var in iterable if cond_expr]
生成器表达式:
(expr for iter_var in iterable if cond_expr)
>>> f = open('test20.py','r')
>>> sum(len(word) for line in f for word in line.split())
391
交叉配对例子:
>>> rows = [1, 2, 3, 17]
>>> def cols():
... yield 56
... yield 2
... yield 1
...
>>> x_product_pairs = ((i,j) for i in rows for j in cols())
>>> for pair in x_product_pairs:
... print pair
...
(1, 56)
(1, 2)
(1, 1)
(2, 56)
(2, 2)
(2, 1)
(3, 56)
(3, 2)
(3, 1)
(17, 56)
(17, 2)
(17, 1)
重构样例:
我们通过一个寻找最长行的例子来看看如何改进代码
例:
---------------------------
#!/usr/bin/env python
f = open('/etc/motd','r')
longest = 0
while True:
linelen = len(f.readline().strip())
if not linelen:
break
if linelen > longest:
longest = linelen
f.close()
print longest
-----------------------------
版本1
--------------------------------
#!/usr/bin/env python
f = open('/etc/motd','r')
longest = 0
allLines = f.readlines()
f.close()
for line in allLines:
linelen = len(line.strip())
if linelen > longest:
longest = linelen
print longest
--------------------------------
版本2
--------------------------------
#!/usr/bin/env python
f = open('/etc/motd','r')
longest = 0
allLines = [x.strip() for x in f.readlines()]
f.close()
for line in allLines:
linelen = len(line)
if linelen > longest:
longest = linelen
print longest
--------------------------------
版本3
----------------------------------
#!/usr/bin/env python
f = open('/etc/motd', 'r')
allLine = [x.strip() for x in f ]
allLineList = []
for Line in allLine:
allLineList.append(len(Line))
print max(allLineList)
----------------------------------
版本4
--------------------------------
#!/usr/bin/env python
f = open('/etc/motd', 'r')
allLineLens = [len(x.strip()) for x in f ]
print allLineLens
f.close()
print max(allLineLens)
--------------------------------
版本5
---------------------------------
#!/usr/bin/env python
f = open('/etc/motd','r')
longest = max (len(x.strip()) for x in f)
f.close()
print longest
---------------------------------
版本6 (最终版)
----------------------------------
>>> print max(len(x.strip()) for x in open('/etc/motd','r'))
74
-----------------------------------
8.14 R相关模块
本文链接:http://www.showerlee.com/archives/992
继续浏览:PYTHON
还没有评论,快来抢沙发!