前言 - 碁峰資訊epaper.gotop.com.tw/pdfsample/a443.pdf · 式來逐一查看它們。...

17
前言 本書要介紹 Python 程式語言,主要的對象是初學者,不過,就算你已經會寫程式,且 想要再學習 Python,這本書也適合你。 本書的節奏不快,會從最基本的開始,一步步帶領你進入更複雜且更多樣的主題。我會 結合食譜與教程的風格來解釋新的名詞與概念,但不會一次說明太多主題。這本書會很 快進入真正的 Python 程式,並頻繁地使用它。 雖然本書的目的,是為了介紹這個語言,但我也會加入一些較進階的主題,例如 NoSQL 資料庫與訊息傳遞程式庫。之所以選擇它們,是因為它們解決某些問題的能力比標準的 方法優秀。之後你要下載並安裝 Python 外部套件,當 Python 內建的功能不適合你的應 用程式時,瞭解它們會有很大的幫助,且嘗試新事物也是件有趣的事情。 我也會介紹一些不能做的案例,特別是當你曾經寫過其他的語言,想要將那些寫法應用 Python 上時。我不會假裝 Python 是個完美的語言,所以會教你如何避免錯誤。 如果有些東西比較難以理解,或有更適合的 Python 風格的做法,我會像 這樣加入一些提示。 對象 本書適合想要學習逐漸成為世界最受歡迎的程式語言的人,無論你是否曾經學過程式 設計。

Upload: others

Post on 13-Oct-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

前言

本書要介紹 Python程式語言,主要的對象是初學者,不過,就算你已經會寫程式,且想要再學習 Python,這本書也適合你。

本書的節奏不快,會從最基本的開始,一步步帶領你進入更複雜且更多樣的主題。我會

結合食譜與教程的風格來解釋新的名詞與概念,但不會一次說明太多主題。這本書會很

快進入真正的 Python程式,並頻繁地使用它。

雖然本書的目的,是為了介紹這個語言,但我也會加入一些較進階的主題,例如 NoSQL資料庫與訊息傳遞程式庫。之所以選擇它們,是因為它們解決某些問題的能力比標準的

方法優秀。之後你要下載並安裝 Python外部套件,當 Python內建的功能不適合你的應用程式時,瞭解它們會有很大的幫助,且嘗試新事物也是件有趣的事情。

我也會介紹一些不能做的案例,特別是當你曾經寫過其他的語言,想要將那些寫法應用

在 Python上時。我不會假裝 Python是個完美的語言,所以會教你如何避免錯誤。

如果有些東西比較難以理解,或有更適合的 Python 風格的做法,我會像

這樣加入一些提示。

對象

本書適合想要學習逐漸成為世界最受歡迎的程式語言的人,無論你是否曾經學過程式

設計。

Page 2: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

vi | 前言

大綱

本書的前七章會解釋 Python的基礎知識,你應該依序閱讀這幾章。之後的章節會說明如何在特定的領域中使用 Python,例如 Web、資料庫、網路等,你可以依你喜歡的順序閱讀。前三個附錄會展示 Python在藝術、商務與科學上的應用。如果你尚未安裝Python 3,接下來你會看到如何安裝它。之後是每章練習題的解答,最後有一些實用的備忘錄。

第一章

程式就像編襪子或烤馬鈴薯的指令。這一章會用一些實際的 Python程式來展示這個語言的外貌、能力,以及在現實世界的用途。Python足以媲美其他的語言,但還是有一些不盡完善的地方。舊版的 Python(Python 2)正逐漸讓位給新版本(Python 3),如果你用的是Python 2的話,請在電腦上安裝 Python 3。請使用互動式解譯器來實驗本書的範例。

第二章

這一章會展示 Python最簡單的資料類型:布林、整數、浮點數,與文字字串。你也會學到基本的數學與文字操作。

第三章

這一章介紹 Python更高層級的內建資料結構:串列、tuple、字典與集合。你可以像樂高積木一樣,用它們來建構更複雜的結構。你會學到如何使用迭代器(iterator)與生成

式來逐一查看它們。

第四章

在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

會看到將程式包裝成函式的方法,並且學會使用例外來處理錯誤。

第五章

本章會展示如何將程式擴充為更大型的程式結構:模組、套件與程式。你會在這裡看

到:程式與資料的放置處、進出傳遞資料、處理選項、瀏覽 Python Standard Library,並看看除了它們之外的選項。

第六章

如果你曾經使用其他語言編寫物件導向程式,Python會讓你比較輕鬆。第六章會解釋何時該使用物件與類別,以及何時該使用模組或串列與字典。

Page 3: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

前言 | vii

第七章

學習像專家一樣管理資料。本章都在討論文字與二進位資料,也就是 Unicode字元與 I/O可為你帶來的樂趣。

第八章

資料都必須被送往別的地方。在本章中,你會從基本的一般檔案、字典,與檔案系統開

始。接下來,你會看到如何處理常見的檔案格式,例如 CSV、JSON與 XML。你也會看到如何用關聯資料庫來儲存與取出資料,甚至看到一些最近的 NoSQL資料存儲。

第九章

這一章專門討論 Web,包括用戶端、伺服器、資料擷取、API與框架。在第九章,你會使用請求參數與範本來處理一個實際的網站。

第十章

這一章討論核心系統。在這章,你會學習管理程式、流程與執行緒,處理資料與時間,

以及將系統管理工作自動化。

第十一章

這一章的主題是網路:服務、協定與 API。本章的範例包括低階的 TCP通訊端、傳訊程式庫、序列系統,及雲端部署。

第十二章

本章提供一些祕訣給 Python開發人員,包括安裝與使用 IDE、測試、除錯、登入、原始碼控制,及文件化。這一章也會協助你尋找並安裝實用的第三方套件、將你自己的程式

包裝起來,供未來重複使用,並瞭解如何找到更多資訊。祝你好運。

附錄 A

第一個附錄會深入討論 Python在以下領域中扮演的角色:圖形、音樂、動畫,與遊戲。

附錄 B

Python在商務領域中有特定的應用:資料視覺化(繪製、圖表及地圖)、安全與監控。

附錄 C

Python在科學界扮演強大的角色:數學與統計學、物理科學、生物科學,與醫學。附錄C也會提到 NumPy、SciPy與 Pandas。

Page 4: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

viii | 前言

附錄 D

如果你尚未在電腦上安裝 Python,這個附錄會教你安裝的方法,無論你用的是Windows、Mac OS/X、Linux或 Unix。

附錄 E

這一章是每章練習題的解答。在你解答之前,不要偷看這個附錄。

附錄 F

這個附錄是可供快速參考的備忘錄。

Python版本程式語言會隨著開發者為它加入新功能與修正錯誤而不斷變化。本書的範例使用 Python 3.3版來編寫與測試。在本書編輯的階段,第 3.4版也被公佈了,所以我會討論它的一些新功能。如果你想要知道 Python被加入什麼,以及何時被加入,可以在 Python的網頁上瀏覽 What’s New in Python(https://docs.python.org/3/whatsnew/)。它是一份技術文

件,對剛要學習 Python的你來說可能有點難懂,但是,如果你將來想要讓你的程式可在安裝各種 Python版本的電腦上運作,這會帶來很大的幫助。

本書編排慣例

本書使用下列的編排規則:

斜體字(Italic)代表新的術語、URL、電子郵件地址、檔案名稱及副檔名。

定寬字(Constant width)用來列舉程式,以及在文章中代表程式的元素,例如變數、函式,及資料類型。

定寬粗體字(Constant width bold)代表要由使用者逐字輸入的指令或其他文字。

定寬斜體字(Constant width italic)代表要換成使用者提供的值,或依上下文而決定的值。

Page 5: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

第四章

Py之殼:程式結構

在第一到三章中,你已經看過許多資料的範例,但還沒有認真地使用它們。大多數的範

例程式使用的都是互動式解譯器,而且都很簡短。現在你會看到如何建立 Python 程式

碼結構,而不是只有資料。

許多電腦語言都會使用大括號({與 })等字元,或關鍵字(例如 begin與 end)來標記一段程式。在這些語言中,使用一致的縮排是一種良好的做法,如此一來,可讓自己與

其他人更容易閱讀程式。市面上甚至有一些工具可以整齊地排列你的程式。

當 Guido van Rossum在設計 Python語言的前身時,他認為縮排本身已足以定義程式的結構了,所以決定省去輸入所有的括號。Python的不尋常之處,在於它用空白字元來

定義程式結構。這是新人會發現的第一個地方,而且對曾經用過其他語言的人來說,這

看起來可能會有點奇怪。但是當你稍微編寫 Python之後,事實證明,你會感覺很自然,並且再也不會有這種感受。你甚至會習慣以更少的打字次數來做更多事情。

用 #來註解註解是在程式中一段會被 Python解譯器忽略的文字。你可能會用註解來解釋附近的Python程式、提醒自己要在某個時刻修復某個東西,或任何其他你要做的事情。你要用#字元來製作註解,從它之後,直到該行結束前的所有東西,都是註解的一部分。你通常會看到獨立的一行註解,如下所示:

>>> # 60 sec/min * 60 min/hr * 24 hr/day>>> seconds_per_day = 86400

Page 6: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

76 | 第四章

或者,被放在註解對象的同一行:

>>> seconds_per_day = 86400 # 60 sec/min * 60 min/hr * 24 hr/day

#字元有很多名稱:hash、sharp、pound,或 sinister-sounding octothorpe1。無論你怎麼

稱呼它 2,它的效果僅止於它的那一行結尾。

Python沒有多行註解。你必須使用 #來明確地開始每一行註解或段落。

>>> #我可以在這裡說任何 Python的壞話,... #因為了不起的井號... #保護著我。...>>>

但是,如果全能的井號被放在文字字串裡面,它的角色會回復成一般的 #字元:

>>> print("No comment: quotes make the # harmless.")No comment: quotes make the # harmless.

用 \來延續多行如果你合理地精簡行數,將會比較容易閱讀程式。我建議每行的字元最長 80個(不一定要如此)。如果你無法在那個長度內說出想說的一切,可使用延續字元:\(反斜線)。你只要在行尾放上 \,Python的動作就會如同它們在同一行一般。

例如,如果我想要用較小的字串來建立一個長字串,可以一步步地做這件事:

>>> alphabet = ''>>> alphabet += 'abcdefg'>>> alphabet += 'hijklmnop'>>> alphabet += 'qrstuv'>>> alphabet += 'wxyz'

我也可以使用延續字元,一次完成:

>>> alphabet = 'abcdefg' + \... 'hijklmnop' + \... 'qrstuv' + \... 'wxyz'

1 就像你身後的那一個八條腿的綠色怪物。

2 不要叫它,不然它可能會再次出現。

Page 7: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 77

如果 Python運算式跨越多行,你也需要使用延續符:

>>> 1 + 2 + File "<stdin>", line 1 1 + 2 + ^SyntaxError: invalid syntax>>> 1 + 2 + \... 36>>>

用 if、elif與 else來比較到目前為止,本書已討論幾乎所有的資料結構了。我們終於要來討論程式結構的最後一

個部分,準備將資料放入程式中(在上一章討論集合的部分,你已經稍微看過它們了,

希望之前沒有造成任何不便)。我們的第一個範例是這個小型的 Python程式,它會檢查布林變數 disaster的值,並印出對應的文字:

>>> disaster = True>>> if disaster:... print("Woe!")... else:... print("Whee!")...Woe!>>>

if與 else這幾行是檢查某個條件是否為 True的 Python 陳述式(在這裡是 disaster的值)。請記得,print()是 Python的內建函式,它可以印出東西,通常會印在你的螢幕上。

如果你曾經寫過其他的語言,注意你不需要在使用 if做測試時加上括號。

不要說 if (disaster == True)之類的話。但你必須在結尾使用冒號(:)。

如果你跟我一樣,有時會忘記輸入冒號,Python會顯示錯誤訊息。

在測試式底下的每一行 print()都要縮排。我使用四個空格來縮排每一個小段落。雖然你可以使用任何縮排型式,但 Python預期同一段落的程式會使用一致的格式—每一行都必須縮進相同的格數,對齊左邊。建議的格式是使用四個空格,稱為 PEP-8(http://

bit.ly/pep-8)。不要使用 tab,或混合使用 tab與空格,它會攪亂縮排格數。

Page 8: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

78 | 第四章

我們在這裡做了很多事情,接下來會完整解釋它們:

• 將布林值 True指派給變數 disaster。

• 使用 if與 else來執行條件比較,根據 disaster的值來執行不同的程式。

• 呼叫 print()函式來印出一些文字

你可以在測試項中加入測試項,依照你的需要來使用任意的階層數目:

>>> furry = True>>> small = True>>> if furry:... if small:... print("It's a cat.")... else:... print("It's a bear!")... else:... if small:... print("It's a skink!")... else:... print("It's a human. Or a hairless bear.")...It's a cat.

在 Python 中,縮排會決定 if與 else段落的配對方式。我們的第一個測試式會檢查furry。因為 furry是 True,Python會前往縮排的 if small測試式。因為我們將 small設為 True,if small相當於 True。這可以讓 Python執行下一行,並印出 It's a cat。

如果你有三個以上的可能性需要測試,可使用 if、elif(意思是 else if)與 else:

>>> color = "puce">>> if color == "red":... print("It's a tomato")... elif color == "green":... print("It's a green pepper")... elif color == "bee purple":... print("I don't know what it is, but only bees can see it")... else:... print("I've never heard of the color", color)...I've never heard of the color puce

在上述範例中,我們使用 ==運算子來測試相等與否。Python的比較運算子有:

相等 ==不相等 !=小於 <

Page 9: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 79

小於等於 <=大於 >大於等於 >=成員資格 in...

它們會回傳布林值 True或 False。我們來看它們是如何動作的,但是在一開始,我們先賦值給 x:

>>> x = 7

現在,我們來測試一些東西:

>>> x == 5False>>> x == 7True>>> 5 < xTrue>>> x < 10True

注意,兩個等號(==)的用途是測試相等與否,一個等號(=)是將值指派給變數。

如果你需要同時做多個比較,可使用布林運算子 and、or與 not來求出最後的布林結果。

布林運算子的優先順序比它們要比較的程式段落還要低。也就是說,程式段落會先被計

算,再做比較。在這個範例中,因為我們將 x設為 7,所以 5 < x會被算出 True,且 x < 10也是 True,所以我們最後得到 True and True:

>>> 5 < x and x < 10True

如同第 25頁的“優先順序”所說的,要避免搞不清楚優先順序,最簡單的方式就是加上括號:

>>> (5 < x) and (x < 10)True

以下是一些其他的測試:

>>> 5 < x or x < 10True>>> 5 < x and x > 10False>>> 5 < x and not x > 10True

Page 10: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

80 | 第四章

如果你將多個比較式 and成為一個變數,Python可讓你這麼做:

>>> 5 < x < 10True

它的效果與 5 < x and x < 10一樣。你也可以編寫較長的比較式:

>>> 5 < x < 10 < 999True

什麼是 True?如果我們檢查的元素不是布林會怎樣? Python是如何認定 True與 False的?

false值不一定非得是 False不可。例如,以下都會被視為 False:

布林 Falsenull None整數零 0浮點數零 0空字串 ''空串列 []空 tuple ()空字典 {}空集合 set()

所有其他的東西都會被視為 True。Python程式會使用這一種“true與否”的定義(或在這個例子中,“false與否”)來檢查空的資料結構以及 False條件:

>>> some_list = []>>> if some_list:... print("There's something in here")... else:... print("Hey, it's empty!")...Hey, it's empty!

如果你要測試的是一個運算式,而不是一個簡單的變數,Python會計算運算式,並回傳布林結果。所以,如果你輸入:

if color == "red":

Python會計算 color == "red"。在稍早的範例中,我們指派字串 "puce"給 color,所以color == "red"是 False,因此 Python會前往下一個測試:

elif color == "green":

Page 11: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 81

用 while來重複執行用 if、elif與 else來測試,程式會從上面執行下面。有時我們需要非一次性的東西。我們需要迴圈,而 Python最簡單的迴圈機制就是 while。使用互動式解譯器來嘗試以下範例,它是一個簡單的迴圈,會印出數字 1到 5:

>>> count = 1>>> while count <= 5:... print(count)... count += 1...12345>>>

我們先將 1指派給 count。while迴圈會比較 count的值是否為 5,如果 count小於或等於5,就會繼續執行。在迴圈中,我們印出 count的值,接著使用陳述式 count += 1將它的值加一。Python會回到迴圈的最上面,再次比較 count的值是否為 5。現在 count的值是 2,所以 while迴圈的內容還是會被執行,因此 count被遞增到 3。

它會繼續下去,直到迴圈最下面將 count由 5遞增到 6,在下一次回到最上面時,count <= 5會是 False,所以 while迴圈會結束。Python會前往下一行。

用 break來取消如果你希望迴圈在發生某個情況時停止,但不確定那件事會在什麼時候發生,可以使用

無窮迴圈以及一個 break陳述式。這次我們會用 Python的 input()函式來讀取一行鍵盤輸入的文字,將它的首字母改成大寫,並印出它。我們會在輸入一行只有 q這個字母的時候跳出:

>>> while True:... stuff = input("String to capitalize [type q to quit]: ")... if stuff == "q":... break... print(stuff.capitalize())...String to capitalize [type q to quit]: testTestString to capitalize [type q to quit]: hey, it worksHey, it works

Page 12: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

82 | 第四章

String to capitalize [type q to quit]: q>>>

用 continue來跳過有時因為某些原因,你不想要跳出迴圈,只想要跳過下一次的迭代。以下是一個故意寫

成的範例,我們要讀取一個整數,如果它是奇數,就印出它的平方,如果它是偶數就跳

過它。我也在裡面加入一些註解。同樣的,我們會使用 q來停止迴圈:

>>> while True:... value = input("Integer, please [q to quit]: ")... if value == 'q': # quit... break... number = int(value)... if number % 2 == 0: # an even number... continue... print(number, "squared is", number*number)...Integer, please [q to quit]: 11 squared is 1Integer, please [q to quit]: 2Integer, please [q to quit]: 33 squared is 9Integer, please [q to quit]: 4Integer, please [q to quit]: 55 squared is 25Integer, please [q to quit]: q>>>

使用 else來檢查中斷如果 while迴圈正常結束(沒有呼叫 break),控制權會被傳給一個選用的 else。當你要編寫一個 while迴圈來尋找某些東西,並且在找到時馬上跳出來時,可以使用這種做法。如果 while迴圈完成,但沒有找到該物件,就會執行 else:

>>> numbers = [1, 3, 5]>>> position = 0>>> while position < len(numbers):... number = numbers[position]... if number % 2 == 0:... print('Found even number', number)... break... position += 1... else: # break not called

Page 13: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 83

... print('No even number found')

...No even number found

else的用法可能沒那麼容易理解,你可以將它想成中斷檢查器(break

checker)。

用 for來迭代基於很好的理由,Python經常會使用迭代器。迭代器可讓你在不知道資料結構有多大,

以及它們的實作方式的情況下遍歷它們。你甚至可以迭代動態建立的資料,處理不適合

被全部放在電腦記憶體內的資料串流。

在 Python中,以這種方式來逐一查看序列是合法的:

>>> rabbits = ['Flopsy', 'Mopsy', 'Cottontail', 'Peter']>>> current = 0>>> while current < len(rabbits):... print(rabbits[current])... current += 1...FlopsyMopsyCottontailPeter

但是我們有更好、更像 Python風格的方式:

>>> for rabbit in rabbits:... print(rabbit)...FlopsyMopsyCottontailPeter

像 rabbits這種串列是可迭代的 Python物件,另外還有字串、tuple、字典、集合,與一些其他的元素。迭代 tuple或串列時,每次會產生一個項目。迭代字串會一次產生一個字元,如下所示:

>>> word = 'cat'>>> for letter in word:

Page 14: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

84 | 第四章

... print(letter)

...cat

迭代字典(或它的 keys()函式)會回傳鍵。這個範例的鍵是桌遊 Clue(Cluedo outside of North America)的卡片類型:

>>> accusation = {'room': 'ballroom', 'weapon': 'lead pipe', 'person': 'Col. Mustard'}>>> for card in accusation: # or, for card in accusation.keys():... print(card)...roomweaponperson

要迭代值,而不是鍵,你可以使用字典的 values()函式:

>>> for value in accusation.values():... print(value)...ballroomlead pipeCol. Mustard

要用 tuple來回傳鍵與值,你可以使用 items()函式:

>>> for item in accusation.items():... print(item)...('room', 'ballroom')('weapon', 'lead pipe')('person', 'Col. Mustard')

請記得,你可以用一個步驟來對一個 tuple賦值。將 items()回傳的 tuple的第一個值(鍵)指派給 card,第二個值(值)指派給 contents:

>>> for card, contents in accusation.items():... print('Card', card, 'has the contents', contents)...Card weapon has the contents lead pipeCard person has the contents Col. MustardCard room has the contents ballroom

Page 15: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 85

用 break來取消for迴圈內的 break會跳出迴圈,它在 while迴圈也是如此。

用 continue來跳過在 for迴圈中插入 continue會跳到下次迴圈迭代,如同它在 while迴圈內的動作。

使用 else來檢查中斷與 while很像,for有一個選用的 else,可檢查 for是否正常結束。如果它沒有執行

break,就會執行 else陳述式。

當你想要確認之前的 for迴圈已完全執行,而不是被 break提早停止時,可使用這個指令。以下範例中的 for迴圈會印出起司的名稱,如果起司店裡面有那一個起司的話,就會中斷迴圈:

>>> cheeses = []>>> for cheese in cheeses:... print('This shop has some lovely', cheese)... break... else: #沒有中斷代表沒有乳酪... print('This is not much of a cheese shop, is it?')...This is not much of a cheese shop, is it?

與 while一樣,同時使用 else與 for可能有點違反直覺。如果你將 for想

成尋找某個東西,在你沒有找到它的時候,就會呼叫 else,這樣會比較容

易理解。如果你想要在不使用 else的情況下,取得相同的效果,可使用

一些變數,來提示你是否在 for迴圈中找到想要的東西,如下所示:

>>> cheeses = []>>> found_one = False>>> for cheese in cheeses:... found_one = True... print('This shop has some lovely', cheese)... break...>>> if not found_one:... print('This is not much of a cheese shop, is it?')...This is not much of a cheese shop, is it?

Page 16: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

86 | 第四章

用 zip()來迭代多個序列這裡還有一種很棒的迭代技巧:使用 zip()函式,以並行的方式來迭代多個序列:

>>> days = ['Monday', 'Tuesday', 'Wednesday']>>> fruits = ['banana', 'orange', 'peach']>>> drinks = ['coffee', 'tea', 'beer']>>> desserts = ['tiramisu', 'ice cream', 'pie', 'pudding']>>> for day, fruit, drink, dessert in zip(days, fruits, drinks, desserts):... print(day, ": drink", drink, "- eat", fruit, "- enjoy", dessert)...Monday : drink coffee - eat banana - enjoy tiramisuTuesday : drink tea - eat orange - enjoy ice creamWednesday : drink beer - eat peach - enjoy pie

zip()會在最短的序列結束時停止。這裡面有一個串列比其他的長(desserts),所以除非我們加長其他的串列,否則沒有人可以拿到 pudding。

第 58頁的“字典”告訴你如何使用 dict()函式,以兩個項目的序列來建立字典,例如tuple、串列,或字串。你可以使用 zip()來逐一查看多個序列,並且將同一個位移值的項目做成 tuple。我們來製作兩個英文與法文單字的 tuple:

>>> english = 'Monday', 'Tuesday', 'Wednesday'>>> french = 'Lundi', 'Mardi', 'Mercredi'

接下來使用 zip()來配對這些 tuple。zip()回傳的值本身並不是 tuple或串列,而是一個可迭代的合併值:

>>> list( zip(english, french) )[('Monday', 'Lundi'), ('Tuesday', 'Mardi'), ('Wednesday', 'Mercredi')]

直接將 zip()的結果傳入 dict(),看吧:一個小型的英法字典!

>>> dict( zip(english, french) ){'Monday': 'Lundi', 'Tuesday': 'Mardi', 'Wednesday': 'Mercredi'}

用 range()來產生數字序列range()函式會回傳指定範圍內的一串數字,讓你不需要先建立並儲存一個諸如串列或tuple等大型資料結構。這可以讓你創建廣大的範圍,且不必用到電腦的任何記憶體,讓你的程式當機。

Page 17: 前言 - 碁峰資訊epaper.gotop.com.tw/PDFSample/A443.pdf · 式來逐一查看它們。 第四章 在第四章,你會結合程式結構與之前幾章提到的資料結構,來做比較、選擇或複製。你

Py之殼:程式結構 | 87

range()的用法很像 slice:range( start, stop, step )。如果你忽略 start,範圍會從 0開始。stop 是唯一必要的值,與 slice一樣,最後一個產生的值是 stop 的前一個。step的預設值是 1,但你可以使用 -1往回走。

如同 zip(),range()會回傳一個可迭代的物件,所以你要用 for ... in來逐一查看值,或將物件轉換成像串列一樣的序列。我們來製作範圍 0、1、2:

>>> for x in range(0,3):... print(x)...012>>> list( range(0, 3) )[0, 1, 2]

以下是製作範圍 2到 0的方式:

>>> for x in range(2, -1, -1):... print(x)...210>>> list( range(2, -1, -1) )[2, 1, 0]

以下的程式會使用 2的 step大小來取得 0到 10間的偶數:

>>> list( range(0, 11, 2) )[0, 2, 4, 6, 8, 10]

其他的迭代器

第八章會介紹迭代檔案的方式。在第六章,你會看到如何迭代自己定義的物件。

生成式

生成式是一種以一或多個迭代器來密集建立 Python資料結構的方式。藉由生成式,你可以結合迴圈與條件測試式,以減少繁瑣的語法。通常會使用生成式就代表你瞭解

Python的程度已經超越初學者等級了。也就是說,你寫的程式更具備 Python風格。