Python---6條件判斷與循環


  條件判斷

計算機之所以能做很多自動化的任務,因為它可以自己做條件判斷。

比如,輸入用戶年齡,根據年齡打印不同的內容,在Python程序中,用if語句實現:

age = 20 if age >= 18: print('your age is', age) print('adult') 

根據Python的縮進規則,如果if語句判斷是True,就把縮進的兩行print語句執行了,否則,什么也不做。

也可以給if添加一個else語句,意思是,如果if判斷是False,不要執行if的內容,去把else執行了:

age = 3 if age >= 18: print('your age is', age) print('adult') else: print('your age is', age) print('teenager') 

注意不要少寫了冒號:

當然上面的判斷是很粗略的,完全可以用elif做更細致的判斷:

age = 3 if age >= 18: print('adult') elif age >= 6: print('teenager') else: print('kid') 

elifelse if的縮寫,完全可以有多個elif,所以if語句的完整形式就是:

if <條件判斷1>: <執行1> elif <條件判斷2>: <執行2> elif <條件判斷3>: <執行3> else: <執行4>
輸入:  輸出:

 

if語句執行有個特點,它是從上往下判斷,如果在某個判斷上是True,把該判斷對應的語句執行后,就忽略掉剩下的elifelse,所以,請測試並解釋為什么下面的程序打印的是teenager

age = 20 if age >= 6: print('teenager') elif age >= 18: print('adult') else: print('kid') 

if判斷條件還可以簡寫,比如寫:

if x: print('True') 

只要x是非零數值、非空字符串、非空list等,就判斷為True,否則為False

注意:返回False、None的時候Python的交互環境不顯示結果。

再議 input

最后看一個有問題的條件判斷。很多同學會用input()讀取用戶的輸入,這樣可以自己輸入,程序運行得更有意思:

birth = input('birth: ') if birth < 2000: print('00前') else: print('00后') 

輸入1982,結果報錯:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module> TypeError: unorderable types: str() > int() 

這是因為input()返回的數據類型是strstr不能直接和整數比較,必須先把str轉換成整數。

Python提供了int()函數來將字符串轉化為數字

s = input('birth: ') birth = int(s) if birth < 2000: print('00前') else: print('00后')

輸入:
輸出:

 

再次運行,就可以得到正確地結果。但是,如果輸入abc呢?又會得到一個錯誤信息:

Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'abc' 

原來int()函數發現一個字符串並不是合法的數字時就會報錯,程序就退出了

如何檢查並捕獲程序運行期的錯誤呢?后面的錯誤和調試會講到。

 

循環

要計算1+2+3,我們可以直接寫表達式:

>>> 1 + 2 + 3 6 

要計算1+2+3+...+10,勉強也能寫出來。

但是,要計算1+2+3+...+10000,直接寫表達式就不可能了。

為了讓計算機能計算成千上萬次的重復運算,我們就需要循環語句。

for...in循環

Python的循環有兩種,一種是for...in循環,依次把list或tuple中的每個元素迭代出來,看例子:

names = ['Michael', 'Bob', 'Tracy'] for name in names: print(name) 

執行這段代碼,會依次打印names的每一個元素:

Michael
Bob
Tracy

所以for x in ...循環就是把每個元素代入變量x,然后每一次都執行縮進塊的語句進行輸出。

再比如我們想計算1-10的整數之和,可以用一個sum變量做累加:

sum = 0 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: sum = sum + x print(sum) 

如果要計算1-100的整數之和,從1寫到100有點困難,

Python提供一個range()函數,可以生成一個整數序列再通過list()函數可以轉換為list。比如range(5)生成的序列是從0開始小於5的整數:

>>> list(range(5)) [0, 1, 2, 3, 4]

range(101)就可以生成0-100的整數序列,計算如下:

 第一種:

輸入:  輸出:

第二種:

輸入:  輸出:

 

注意縮進,會輸出不一樣的結果:

輸入:  輸出:

 

while循環

 第二種循環是while循環,只要條件滿足,就不斷循環,條件不滿足時退出循環,輸出的是最后一個循環的結果。

比如我們要計算100以內所有奇數之和,可以用while循環實現:

sum = 0 n = 99 while n > 0: sum = sum + n n = n - 2 print(sum) 

在循環內部變量n不斷自減,直到變為-1時,不再滿足while條件,循環退出。

 輸入:  輸出:

 

break

在循環中,break語句可以提前退出循環,程序結束。例如,打印出1~10后,緊接着打印END,程序結束。

n = 1 while n <= 100: if n > 10: # 當n = 11時,條件滿足,執行break語句 break # break語句會結束當前循環 print(n) n = n + 1 print('END')

continue

在循環過程中,也可以通過continue語句,跳過當前的這次循環,直接開始下一次循環。

 如果我們想只打印 1-10之間的奇數,可以用continue語句跳過某些循環:

n = 0 while n < 10: n = n + 1 if n % 2 == 0: # 如果n是偶數,執行continue語句 continue # continue語句會直接繼續下一輪循環,后續的print()語句不會執行 print(n) 

執行上面的代碼可以看到,打印的不再是1~10,而是1,3,5,7,9。

可見continue的作用是提前結束本輪循環,並直接開始下一輪循環

 

小結

break語句可以在循環過程中直接退出循環,而continue語句可以提前結束本輪循環,並直接開始下一輪循環。這兩個語句通常都必須配合if語句使用。

要特別注意,不要濫用breakcontinue語句。breakcontinue會造成代碼執行邏輯分叉過多,容易出錯。大多數循環並不需要用到breakcontinue語句,上面的兩個例子,都可以通過改寫循環條件或者修改循環邏輯,去掉breakcontinue語句。

有些時候,如果代碼寫得有問題,會讓程序陷入“死循環”,也就是永遠循環下去。這時可以用Ctrl+C退出程序,或者強制結束Python進程。

 

dict,{}

Python內置了字典:dict的支持,dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。

舉個例子,假設要根據同學的名字查找對應的成績,如果用dict實現,只需要一個“名字”-“成績”的對照表,直接根據名字查找成績,無論這個表有多大,查找速度都不會變慢。用Python寫一個dict如下:

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95

這種key-value存儲方式,在放進去的時候,必須根據key算出value的存放位置,這樣,取的時候才能根據key直接拿到value。

把數據放入dict的方法,除了初始化時指定外,還可以通過key放入

>>> d['Adam'] = 67 >>> d['Adam'] 67 

由於一個key只能對應一個value,所以,多次對一個key放入value,后面的值會把前面的值沖掉

>>> d['Jack'] = 90 >>> d['Jack'] 90 >>> d['Jack'] = 88 >>> d['Jack'] 88
>>> d
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85,'Adam':67,'Jack':88}

如果key不存在,dict就會報錯:

>>> d['Thomas']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module> KeyError: 'Thomas' 

要避免key不存在的錯誤,有兩種辦法,一是通過in判斷key是否存在

>>> 'Thomas' in d False 

二是通過dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value

>>> d.get('Thomas') >>> d.get('Thomas', -1) -1 

注意:返回None的時候Python的交互環境不顯示結果。

刪除一個key,用pop(key)方法,對應的value也會從dict中刪除

>>> d.pop('Bob') 75 >>> d {'Michael': 95, 'Tracy': 85} 

請務必注意,dict內部存放的順序和key放入的順序是沒有關系的。

和list比較,dict有以下幾個特點:

  1. 查找和插入的速度極快,不會隨着key的增加而變慢;
  2. 需要占用大量的內存,內存浪費多。

而list相反:

  1. 查找和插入的時間隨着元素的增加而增加;
  2. 占用空間小,浪費內存很少。

所以,dict是用空間來換取時間的一種方法。

dict可以用在需要高速查找的很多地方,在Python代碼中幾乎無處不在,正確使用dict非常重要,需要牢記的第一條就是dict的key必須是不可變對象

這是因為dict根據key來計算value的存儲位置,如果每次計算相同的key得出的結果不同,那dict內部就完全混亂了。這個通過key計算位置的算法稱為哈希算法(Hash)。

要保證hash的正確性,作為key的對象就不能變。

在Python中,字符串、整數等都是不可變的,因此,可以放心地作為key。而list是可變的,就不能作為key

>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'

set

set和dict類似,也是一組key的集合,但不存儲value。由於key不能重復,所以,在set中,沒有重復的key。

創建一個set,需要提供一個list作為輸入集合

>>> s = set([1, 2, 3]) >>> s {1, 2, 3} 

注意,傳入的參數[1, 2, 3]是一個list,而顯示的{1, 2, 3}只是告訴你這個set內部有1,2,3這3個元素,顯示的順序也不表示set是有序的。。

重復元素在set中自動被過濾:

>>> s = set([1, 1, 2, 2, 3, 3]) >>> s {1, 2, 3} 

通過add(key)方法可以添加元素到set中,可以重復添加,但不會有效果

>>> s.add(4) >>> s {1, 2, 3, 4} >>> s.add(4) >>> s {1, 2, 3, 4} 

通過remove(key)方法可以刪除元素

>>> s.remove(4) >>> s {1, 2, 3} 

set可以看成數學意義上的無序和無重復元素的集合,因此,兩個set可以做數學意義上的交集、並集等操作:

>>> s1 = set([1, 2, 3]) >>> s2 = set([2, 3, 4]) >>> s1 & s2 {2, 3} >>> s1 | s2 {1, 2, 3, 4} 

set和dict的唯一區別僅在於沒有存儲對應的value,但是,set的原理和dict一樣,所以,同樣不可以放入可變對象,因為無法判斷兩個可變對象是否相等,也就無法保證set內部“不會有重復元素”。試試把list放入set,看看是否會報錯。

 

再議不可變對象

上面我們講了,str是不變對象,而list是可變對象。

對於可變對象,比如list,對list進行操作,list內部的內容是會變化的,比如:

>>> a = ['c', 'b', 'a'] >>> a.sort() >>> a ['a', 'b', 'c'] 

而對於不可變對象,比如str,對str進行操作呢:

>>> a = 'abc' >>> a.replace('a', 'A') 'Abc' >>> a 'abc' 

雖然字符串有個replace()方法,也確實變出了'Abc',但變量a最后仍是'abc',應該怎么理解呢?

我們先把代碼改成下面這樣:

>>> a = 'abc' >>> b = a.replace('a', 'A') >>> b 'Abc' >>> a 'abc' 

要始終牢記的是,a是變量,而'abc'才是字符串對象!有些時候,我們經常說,對象a的內容是'abc',但其實是指,a本身是一個變量,它指向的對象的內容才是'abc'

┌───┐                  ┌───────┐
│ a │─────────────────>│ 'abc' │
└───┘                  └───────┘

當我們調用a.replace('a', 'A')時,實際上調用方法replace是作用在字符串對象'abc'上的,而這個方法雖然名字叫replace,但卻沒有改變字符串'abc'的內容。相反,replace方法創建了一個新字符串'Abc'並返回,如果我們用變量b指向該新字符串,就容易理解了,變量a仍指向原有的字符串'abc',但變量b卻指向新字符串'Abc'了:

┌───┐                  ┌───────┐
│ a │─────────────────>│ 'abc' │
└───┘                  └───────┘
┌───┐                  ┌───────┐
│ b │─────────────────>│ 'Abc' │
└───┘                  └───────┘

所以,對於不變對象來說,調用對象自身的任意方法,也不會改變該對象自身的內容。相反,這些方法會創建新的對象並返回,這樣,就保證了不可變對象本身永遠是不可變的。

小結

使用key-value存儲結構的dict在Python中非常有用,選擇不可變對象作為key很重要,最常用的key是字符串。

tuple雖然是不變對象,但試試把(1, 2, 3)(1, [2, 3])放入dict或set中,並解釋結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM