0基礎學Python之九:循環語句(下)
Hi 大家好,我是王可樂。上一節課里,可樂為大家介紹了 WHILE 循環語句,並且演示了如何使用 BREAK 和 CONTINUE 來控制循環語句的執行邏輯。
通過循環來重複執行一段邏輯是程序設計裡面最常見的流程之一,在今天的課程里,可樂再為大家介紹一下另一個循環語句,FOR 語句。FOR 循環語句很多時候更加簡潔,而且可以很優美地用在我們後面要為大家介紹的數組、字典以及可遍歷對象上。今天我們只為大家簡單介紹 FOR 循環語句的用法,在後面的課程中,可樂還會再為大家補充它的更多用法。
>>> largest = 0 # 首先定義一個變數叫 largest>>> counts = [1, 5, 7, 2, 4, 9, 3, 3, 6] # 然後我們定義一個列表,它保存了一些正整數,我們假設這些數是一些計數值,我們要用 FOR 循環來找到其中的最大值>>> for x in counts: if x > largest:... largest = x # 然後我們定義 if 子句,當 x 大於 largest 時,將 x 賦值給 largest... # 回車,執行這個 FOR 循環>>> print(largest)9
我們先來看一下結果,輸入 print(largest),可以看到,程序正確找出了最大值 9。在上面這段程序里,for x in counts 這句話的意思是,依次取出 counts 裡面的數字,賦予給 x,然後以這個 x 值來執行 for 的循環體,直至取完所有 counts 數組裡的數字。在循環體里,我們判斷當前 x 的值是否大於當前的 largest,如果 x 更大,那就把 largest 更新成當前的最大值,否則就什麼也不做。最終,程序一一檢查了所有 counts 里的數字,找到了最大值 9。
下面再來看一個例子。這次我們重新實現一次前面從 1 加到 100 的代碼,只是換成 FOR 語句:
>>> total = 0 # 首先,定義 total 變數,等於零>>> for x in range(1, 101): # 然後,念,回車... total += x # 然後是四個空格,輸入循環體,total += x,回車... # 再回車,執行這個循環體>>> print(total)5050
我們先來看一下結果,輸入 print(total) 回車,答案是 5050。
在這個 FOR 循環里有一個新東西,range。這個看起來像是函數的東西,其實是一個對象。不過大家不用擔心對象這個新名詞,後面的課程中可樂還會為大家介紹。現在大家只需要知道,range(1, 101) 定義了一個 range 對象,而這個對象是可遍歷的。也就是說,當我們用 for x in 去訪問這個 range 時,range 對象會依次為我們提供 1,2,3 直到 100 總共 100 個數字,就像是我們在訪問一個超長的,從 1 到 100 的數組一樣。
range 還有很多其他的用法,這裡大家只需要先學會這一種,使用兩個參數來定義 range()。要注意,range(1, 101) 的第一個參數 1 是起始值,它包含在最終的序列里,而後一個參數結束值則不包含在最終的序列里。
這種 for x in 的循環定義看起來更加簡潔清晰,對於訪問數組、range 以及後面我們會講到的字典以及其他可遍歷對象來說,for x in 是一個很好的選擇。
和 WHILE 循環類似,FOR 循環語句也支持後面添加一個 ELSE 子句,在 FOR 循環執行結束之後運行。同樣地,FOR 循環也可以使用 break 和 continue 來控制循環的執行,而 for 循環被 break 終端執行時,如果有還有 else 語句,那麼 else 語句也不會被執行,和 while 循環行為一樣。
此外,就像循環體裡面可以使用 IF 條件語句一樣,循環體裡面也可以再使用循環語句,並且內部循環的循環體裡面還可以使用循環。這種代碼稱作多重循環,或者循環嵌套。我們再來看一個例子,這個例子中我們要找出一個字元串里是否有重複字元。例如字元串 Hello 里,l 就是裡面的重複字元,因為它總共出現了兩次。
我們先來想一下思路。給你任意一個字元串,該怎麼判斷裡面是否有重複字元呢?最簡單的想法,那就是一個字元一個字元的去找咯。
首先我們考慮第一個字元,去找整個字元串里除了它自己還有沒有跟它一樣的字元;如果有,那就得到結論字元串里有重複字元,如果沒有那就繼續考慮第二個字元,還是到整個字元串裡面找是否有和它重複的字元;如果還沒找到,那就一直重複下去;如果我們一直找到最後一個字元,也沒有發現哪個字元在字元串里有重複字元,那就得出結論,整個字元串里都沒有重複字元。思路有了,那麼來寫代碼吧。
>>> s = "Dont panic!" # 首先我們來試一個短的字元串,Dont panic!>>> for i in range(0, len(s)-1): # 然後,念代碼,這裡我們產生一個 i,它從字元串第一個下標 0 開始,一直到字元串長度減一,也就是字元串最後一個字元的下標;... for j in range(i+1, len(s)-1): # 然後在循環體內,我們產生一個 j,它從當前 i 的後一個字元開始,直到最後一個字元... if s[i] == s[j]: # 然後,我們判斷兩個字元 s[i] 和 s[j] 是否相同... print(存在相同字元,下標 {} 和 {}.format(i, j)) # 如果相同,那麼我們就找到了相同字元,列印出來... break...存在相同字元,下標2和8>>>
第一次看到這樣的代碼,不要慌張,我們來人工推演一下:
- 在第一層循環里,我們使用下標 i 從頭到尾依次遍歷所有字元,代碼開始運行是,i 的值是 0,指向字元 D
- 然後我們進入循環體,這時我們使用下標 j,從 i + 1,也就是下標 1 的第二個字元開始直到最後一個字元,最開始我們的 j 值為 1,也就是第二個字元 o
- 然後我們對比 D 和 o 是否相等,發現他們不相等,IF 語句裡面的語句不執行,內層循環進入第二次運行,此時 j 值為 2,也就是字元 n
- 然後我們對比發現 D 和 n 也不相等,如此 j 從 1 增加到 11,因為所有字元和 D 都不相同,所以循環里的 IF 語句一直不成立
- 內層循環執行一遍之後,外層循環執行一步,此時 i 為 1,也就是字母 o
- 此時內層循環 j 從 o 的後一個字元開始向後一一比較,為什麼前面的不比較了呢,因為在上一次循環時候,我們已經比較過 D 和 o 了
- 字元 o 向後一一比較的結果我們很容易能看出來,仍然是沒有和 o 重複的字元,於是外層循環繼續執行一步,對比字元 n 和後面的所有字元是否有相同
我們來查看一下執行結果,發現重複字元下標 2 和 8。確實是發現了上述字元串的第三個字元和第九個字元都是 n。
我們可以很容易看到,在這個雙重循環里,對於外層循環的每一步,內層循環都要執行許多步。如果內層循環再嵌套一層循環,循環深度繼續增加,程序執行的總步數也會飛快的增長。程序需要運行的步數顯然直接影響了程序運行的速度,大部分時候我們都希望設計運行速度快的程序,因此就要非常慎重的考慮多重循環。
解決同一個問題可能會存在很多方法,不同的方法寫出程序運行速度不同,在計算機領域我們使用複雜度來描述一個演算法的效率,這是一個非常深刻的問題,我們會在後面的課程來介紹。
好了,今天的內容就到這裡。學習完今天的內容,大家就已經掌握了 Python 編程中的全部主要流程式控制制方法。使用這些流程式控制制,你可以實現非常豐富的計算邏輯,讓計算機幫你完成更加複雜的任務。
在下一節課程里,可樂會開始為大家介紹 Python 中的一些重要的內置數據結構,讓你可以更加自由的表示和使用數據。那麼,下期再見咯。
推薦閱讀: