Python學習筆記-第五章 條件、循環和其他語句(下)



第五章 條件、循環和其他語句

5.5 循環

5.5.1 while循環

name=''
while not name:
	name=input('please enter your name:')
	print('hello,%s!' % name)

5.5.2 for 循環

words=['this','is','an','ex','parrot']
for word in words:  #這裏的for如果換成while,會報錯,word沒有定義過。
	print(word)
#打印1~100的數字
for number in range(1,101):
    print(number)
能用for循環就儘量不要用while循環

range(0,10)  #返回值range(0,10)。range函數包括下限,不包含上限。
range(10)   #返回值range(0,10),python3後有變化,xrange不存在。

5.5.3 循環遍歷字典元素

d={'x':1,'y':2,'z':3}
for key in d:
	print(key,'corresponds to',d[key])  #返回值x corresponds to 1 y corresponds to 2 z corresponds to 3
for key.value in d.items():  #會報錯,字符串不能用value。
    print(key,'corresponds to',value)

5.5.4 一些迭代工具

1.並行迭代

同時迭代兩個序列。

names=['anne','beth','george','damon']
ages=[12,45,32,102]
for i in range(len(names)):
	print(names[i],'is',ages[i],'years old.') #返回值anne is 12 years old.beth is 45 years old.george is 32 years old.damon is 102 years old.
zip(names,ages)  #返回值<zip object at 0x00000000035C0C08>,新版本變化。
for name,age in zip(names,ages):
    print(name,'is',age,'years old')  #返回結果同上個例子。
zip(range(5),range(100000000))  #後一個原文推薦xrange,但是這個函數在新版本中已經不存在。返回值<zip object at 0x00000000035DDEC8>

2.編號迭代

#在一個字符串列表中替換所有包含‘xxx'的子字符串
for string in strings:
	if 'xxx' in string:   #如果string中含有'xxx'子字符串則往下執行
		index=strings.index(string)   #獲取有'xxx'子字符串的字符的編號
		string[index]='[censored]'   #將該字符替換爲[censored]。這段代碼只是一部分,無法單獨執行。
#更好的方法
for string in strings:
    if 'xxx' in string:
        strings[index]='[censored]'
        index+=1  #加了這一行代碼會更好,搜索不會返回錯誤的索引。

#使用內建enumerate函數
for index.string in enumerate(strings):
    if 'xxx' in string:
        string[index]='[censored]' #報錯,'int' object has no attribute 'string'

3.翻轉和排序迭代

>>> sorted([4,3,6,8,3])  #返回列表
[3, 3, 4, 6, 8]
>>> sorted('Hello,world!')
['!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed('Hello,world!'))
['!', 'd', 'l', 'r', 'o', 'w', ',', 'o', 'l', 'l', 'e', 'H']
>>> ''.join(reversed('Hello,world!'))
'!dlrow,olleH'

5.5.5 跳出循環

循環會一直執行到條件爲假,或者序列元素用完時。如果想要提前結束循環。

1.break

from math import sqrt
for n in range(99,0,-1):  #-1是range函數的第三個參數,表示步長,每對相鄰數字之間的差別,負值表示反向迭代
	root=sqrt(n)
	if root==int(root):
		print(n)
		break  #第一次執行完後就結束了,返回值爲81.
2.continue

讓當前迭代結束,“跳”到下一輪循環的開始。

5.5.6 循環中的else子句

循環內使用break語句,通常是因爲“找到”了某物或某事“發生了。如果想要在沒有跳出之前做些事情,可以用布爾變量,在循環前將其設定爲False,跳出後設定爲True,然後用if語句查看循環是否跳出。

broke_out=False
for x in seq:
	do_something(x)
	if condition(x):
		broke_out=True
		break
	do_something_else(x)
	if not broke_out:
		print("I didn't break out!")
更簡單的方法,循環中增加else

from math import sqrt
for n in range(99,81,-1):  
	root=sqrt(n)
	if root==int(root):
		print(n)
		break            #只要找到一個平方數,就結束循環,沒有找到就做else後面的事情。測試過不加break,結果沒有變化。
	else:
 		print("didn't find it!")  #結果一共打印了18個didn't find it.

5.6 列表推導式——輕量級循環

列表推導式是利用其它列表創建新列表(類似集合推導),工作方式類似於for循環

 <pre name="code" class="python">>>>[x*x for x in range(10)]  #打印平方數
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x%3==0]  #打印能被3整除的平方數
[0, 9, 36, 81]
>>> [(x,y) for x in range(3) for y in range (3)]   #創建列表
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

也可以用for 循環
result=[]
for x in range(3):
	for y in range(3):
		result.append((x,y))   #這裏沒有輸出語句,所以代碼寫完不會有任何反饋結果。但是result的結果已經變了。


girls=['alice','bernice','clarice']
boys=['chris','arnold','bob']
[b+'+'+g for b in boys for g in girls if b[0]==g[0]]  #返回首字母相同的男孩和女孩。

#推薦的代碼
girls = ['alice','bernice','clarice']
boys  = ['chris','arnold','bob']
for girl in girls:
letterGirls.setdefault(girl[0],[]).append(girl)
print([b+'+'+g for b in boys for g in letterGirls[b[0]]])  #一直報錯

Traceback (most recent call last):
  File "<pyshell#121>", line 3, in <module>
    print([b+'+'+g for b in boys for g in letterGirls[b[0]]])
  File "<pyshell#121>", line 3, in <listcomp>
    print([b+'+'+g for b in boys for g in letterGirls[b[0]]])
KeyError: 'c'

5.7 三人行

5.7.1 什麼都沒發生

pass在代碼中做佔位符用。

if name=='Ralph Auldus Melish':
	print('Welcome!')
elif name=='Enid':
	pass   #表示還沒完,如果不寫這個,會報錯,空代碼塊是非法的。
elif name=='Bill Gates':
	print('Access Denied')

5.7.2 使用del刪除

 scoundrel={'age':42,'first name':'Robin','last name':'of Locksley'}
>>> robin=scoundrel
>>> scoundrel
{'age': 42, 'last name': 'of Locksley', 'first name': 'Robin'}
>>> robin
{'age': 42, 'last name': 'of Locksley', 'first name': 'Robin'}
>>> scoundrel=None
>>> robin   #scoundrel與字典解綁時不影響robin的使用
{'age': 42, 'last name': 'of Locksley', 'first name': 'Robin'} 
>>> robin=None #字典沒有任何名字綁在它上面,會被直接刪除
x=1
del x
x #報錯,x不存在了。
x=['Hello','world']
y=x
y[1]='python'
x  #返回['Hello', 'python']
del x
y  #返回['Hello', 'python'],x的刪除對y不影響。刪除的只是名字,而不是列表本身。python無法通過代碼刪除值,當某個值不再使用時,解釋器會負責內存的回收。

5.7.3 使用exec和eval執行和求值字符串

1.exec

exec最有用的地方是可以動態的創建代碼字符串。

exec("print( 'Hello world!')")  #又是該死的版本差異。
from math import sqrt
scope={}
exec('sqrt=1', scope) #不用scope會報錯,scope是起到放置代碼字符串命名空間作用的字典。
sqrt(4)  #返回值2.0
scope['sqrt']  #返回值1,原來的函數能正常使用

2.eval

用於求值,是類似於exec的內建函數。

eval(input("Enter an arthmetic expression:"))
Enter an arthmetic expression:6+18*2
42
初探作用域

>>> scope={}
>>> scope['x']=2
>>> scope['y']=3
>>> eval('x*y',scope)
6
>>> scope={}
>>> exec("x=2",scope)
>>> eval('x*x',scope)
4 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章