# Chapter 0 - Python 簡介
### 1. Python 是什麼?
Python 是一種高級、解釋型的通用程式語言,由 **Guido van Rossum** 在 1989 年於荷蘭的國家數學和計算機科學研究所(CWI)開發。其設計哲學強調代碼的可讀性和簡潔性,讓程序員能夠以更直觀的方式表達想法,從而提高開發效率。
值得注意的是,Python 的名字並非來自於蟒蛇,而是取自英國的喜劇團體 **「蒙提·派森的飛行馬戲團」(Monty Python's Flying Circus)**。Guido van Rossum 是該節目的粉絲,因而以此命名。
Python 使用縮排(whitespace indentation)來定義程式結構,而非依賴大括號 {} 或關鍵字,這種設計使得代碼更為整潔、易讀。
Python 的傳統且最受歡迎的實現版本是 CPython,它是用 C 語言編寫的。
Python 附帶的標準庫大多是用 Python 本身編寫的,其他部分則是使用 C 語言編寫或內部使用 C 語言庫。
[CPython vs Cython](https://www.tutorialspoint.com/what-is-the-difference-between-cython-and-cpython)
Cython 和 CPython 的主要差異在於它們的執行方式:
1. **CPython** 是 Python 語言的預設實現。它是一種直譯器,將 Python 代碼轉換為機器碼,以便執行。由於 Python 是解釋執行的,因此速度相對較慢。
2. **Cython** 是 Python 的超集,允許將 Python 代碼編譯為 C 程式碼,以提高執行速度。Cython 能夠與 C/C++ 函數互操作,因此速度上比 CPython 更快,但需要安裝 C 編譯器。
目前,Python 主要有兩個版本分支:Python 2 和 Python 3。Python 2 已於 2020 年停止支援,Python 3 是現今主流且持續更新的版本。在本課程中,我們將專注於 **Python 3** 的學習。
### 2. 編程語言的分類
在深入瞭解 Python 之前,我們先來了解一下編程語言的分類,以及它們在不同領域的應用。編程語言通常可以分為低階語言和高階語言。
#### 低階通用編程語言
低階語言更接近機器語言,提供對硬體資源的直接控制,通常用於需要高效能和硬體交互的場景。
| 語言 | 優點 | 缺點 | 活躍領域 |
|----------------|------------------------------------------------------------|--------------------------------------------------------|--------------------------------------------------|
| **Assembly** | - 高效,接近機器碼,執行速度極快。<br>- 完全控制硬體資源。 | - 可讀性差,開發難度大。<br>- 對特定硬體架構有依賴性。 | - 系統軟體開發(操作系統、驅動程式)。<br>- 嵌入式系統。 |
| **C** | - 高效且提供底層操作控制。<br>- 跨平台支持。 | - 手動管理記憶體容易出錯。<br>- 開發難度較高。 | - 系統程式設計(作業系統、硬體控制)。<br>- 嵌入式系統。 |
#### 高階通用編程語言
高階語言更接近人類語言,抽象程度高,開發效率高,適用於各種應用領域。
| 語言 | 優點 | 缺點 | 活躍領域 |
|-----------------|-------------------------------------------------------------------------|---------------------------------------------------------------|--------------------------------------------------------------------|
| **Python** | - 易學易用,語法簡單。<br>- 豐富的庫與框架支持各種應用。 | - 執行速度慢於 C/C++。<br>- 動態類型可能導致大型專案的效能瓶頸。| - 人工智慧、數據分析。<br>- 網站開發、機器學習、科學計算。 |
| **Java** | - 跨平台支持,使用 JVM 實現一次編寫,到處運行。<br>- 內建垃圾回收機制。 | - 比 C 語言慢,記憶體佔用相對較高。 | - 企業級應用開發。<br>- Android 開發。<br>- Web 後端開發。 |
| **JavaScript** | - 廣泛應用於前端開發,無需安裝即可執行。<br>- 生態系統和工具豐富。 | - 效能相對較低。<br>- 動態語言的錯誤調試較困難。 | - Web 前端開發。<br>- 全端開發。<br>- 網頁應用程式開發。 |
| **C++** | - 高效、靈活,支援多種編程範式。<br>- 底層控制力強。 | - 複雜性高,編程和除錯難度大。<br>- 記憶體管理複雜。 | - 遊戲開發。<br>- 高效能系統和應用程式開發。<br>- 圖形處理、嵌入式系統。 |
| **Go** | - 高效且簡潔,適合並發程式設計。<br>- 內建垃圾回收機制。 | - 庫相對較少,生態系統較小。 | - 後端開發。<br>- 雲端服務和微服務開發。 |
| **Ruby** | - 開發效率高,適合快速原型設計。<br>- 語法簡單,適合初學者。 | - 效能較低,不適合高效能應用程式。 | - 網站開發(Ruby on Rails)。<br>- 原型設計。 |
| **Swift** | - 專為 iOS 和 macOS 開發設計,語法簡單且安全。 | - 僅限於 Apple 生態系統,不具跨平台性。 | - iOS 和 macOS 應用程式開發。 |
#### 總結
- **低階語言**:效能高、硬體控制能力強,但開發難度大,主要用於系統層級和嵌入式領域。
- **高階語言**:語法簡潔,開發效率高,應用範圍廣泛,適用於 Web、移動應用和數據處理等領域。
**Python** 作為高階通用編程語言的代表之一,因其易用性和廣泛的應用領域,成為許多開發者的首選語言。
### 3. 為什麼要學習 Python?
學習 Python 有許多優點,以下是一些關鍵的理由:
- **簡單易學**:Python 的語法簡潔明了,接近自然語言,使初學者能夠更快地上手。
例如,一個加法操作在 Python 中只需最多 4 行代碼,而在 Java 或 C 中需要更多行。
**Java 實現:**
```java
int tmp = var1;
var1 = var2;
var2 = tmp;
```
**Python 實現:**
```python
var1, var2 = var2, var1
```
- **高生產力**:Python 的高級數據結構和動態類型,以及豐富的標準庫,使開發者可以更快速地編寫和維護程式。
- **可讀性強**:統一的編碼風格和嚴格的縮排規則,使代碼易於閱讀和維護,有利於團隊協作。
**Pythonic 風格**:[命名方式](https://cflin.com/wordpress/603/pep8-python%E7%B7%A8%E7%A2%BC%E8%A6%8F%E7%AF%84%E6%89%8B%E5%86%8A)、[語法糖](https://www.11meigui.com/2023/python3-shortcut.html)
- **廣泛的應用領域**:Python 被廣泛應用於金融分析、機器學習、深度學習、統計學、Keras、TensorFlow 、網頁開發、資料分析、人工智慧、科學計算、自動化測試、遊戲開發等領域都有廣泛的應用。如果你有興趣進入資料科學及人工智能領域的方向,學習 Python 是一個必備的前提。
- **開源**:Python 是開源的,這意味著你可以根據自己的需求 **"修改"** 它,甚至可以查看其源碼來深入理解它的運作原理。
- **龐大的社群支援**:活躍的開發者社群和大量的第三方庫 [GITHUB](https://github.com/),能夠滿足各種開發需求,並提供豐富的學習資源。
- **跨平台運行**:Python 可以在 Windows、macOS、Linux 等多個作業系統上運行,具有良好的可移植性。
### 4. Python 的缺點
儘管 Python 有許多優點,但也存在一些不足之處:
- **執行速度較慢**:由於 Python 是直譯型語言,相較於編譯型語言如 C 或 C++,執行速度較慢。但在許多應用中,這個缺點可以通過優化代碼或使用 C 擴展模組來彌補。
- **[直譯及編譯的不同](https://totoroliu.medium.com/%E7%B7%A8%E8%AD%AF%E8%AA%9E%E8%A8%80-vs-%E7%9B%B4%E8%AD%AF%E8%AA%9E%E8%A8%80-5f34e6bae051)**
- **移動端支援不足**:Python 在移動端開發上不如 Swift(iOS)或 Kotlin(Android)那麼普及,適合開發商業級移動應用的框架較少。
- **多線程支持不佳**:Python 的全域解釋器鎖(GIL)限制了多線程的性能,但可以通過多進程或協程來實現並行處理。
### 5. 如何下載和安裝 Python?
要開始使用 Python,可以從以下方式下載和安裝:
- **Python 官方網站**:前往 [Python.org](https://www.python.org/downloads/) 下載適用於你的作業系統的最新版本。
- **Anaconda**:如果你從事資料科學或機器學習,建議使用 [Anaconda](https://www.anaconda.com/products/individual),它集成了 Python 環境和常用的科學計算庫。
- **Windows 用戶**:可以直接從 Microsoft Store 下載 Python,方便安裝和更新。
- **macOS 用戶**:macOS 通常預裝了 Python 2,建議從官方網站下載並安裝 Python 3,或使用包管理器如 Homebrew 進行安裝。
- **Linux 用戶**:大多數 Linux 發行版都預裝了 Python,可以使用包管理器進行更新或安裝。
### 6. 開發環境選擇
選擇合適的開發環境有助於提高編程效率:
- **IDLE**:Python 自帶的簡單集成開發環境,適合初學者。
- **PyCharm**:由 JetBrains 開發的專業 Python IDE,功能強大,提供免費的社群版。
- **Visual Studio Code**:輕量級的代碼編輯器,通過安裝 Python 擴展,可以提供良好的開發體驗。
- **Jupyter Notebook**:適合資料分析和機器學習,支持即時運算和結果可視化。
- **應用方面**:[Python 應用方面](https://ithelp.ithome.com.tw/m/articles/10294207)
### 7. 課程內容
在本課程中,我們將深入學習以下內容:
- **Python 基本語法和資料型別**:瞭解 Python 的基本結構和常用的資料型別。
- **運算符與控制流**:學習如何使用運算符和控制結構(如條件語句和迴圈)來控制程式流程。
- **函式與模組**:掌握如何定義函式、使用內建函式和模組,提高代碼的重用性。
- **檔案 I/O 操作**:學習如何讀寫檔案,處理各種檔案格式。
- **物件導向程式設計**:瞭解類和物件的概念,學習如何使用 OOP 原則進行程式設計。
- **錯誤與異常處理**:學習如何捕獲和處理異常,提升程式的健壯性。
- **進階主題**:包括生成器、裝飾器、上下文管理器等高級特性。
- **標準庫與第三方庫**:熟悉 Python 的標準庫,學習如何安裝和使用第三方庫。
- **實戰應用**:通過項目實踐,如網頁爬蟲、資料庫操作、郵件處理等,將所學知識應用到實際問題中。
---
透過第零章的介紹,相信你對 Python 有了初步的了解。Python 的簡潔性和強大功能,使其成為現代編程領域中不可或缺的一部分。在接下來的章節中,我們將從基礎開始,逐步深入學習 Python,並探索其在各個領域的應用。讓我們一起踏上這段充滿樂趣的學習之旅吧!
# Python 課程 Chapter 1 筆記
## 1. 課程概述
- Chapter 1 的重點是 <font size="5" color="red">**基本語法 (syntax)** 和 **資料型態 (data types)**</font> 。
- 了解這些資料型態非常重要,因為它們是理解更複雜內容的基礎。
- **必須記住 Python 的語法規則**,包括<font size="5" color="red">**大小寫敏感**、**縮排**、**資料型態**</font>的使用。
## 2. Python 語法
- **大小寫敏感**:Python 區分大小寫,`A` 和 `a` 是不同的變數。
- **縮排 (indentation)**:Python 透過縮排來標識程式碼區塊,而不是使用 `{}` 或 `;`。
- **一致的縮排**:可使用 `tab` 或 `space`,但不能混用。
## 3. Python 資料型態
- **整數 (int)**:表示整數,如 `5`。
- **浮點數 (float)**:表示帶小數點的數值,如 `3.14`。
- **字串 (string)**:有序的字元序列,如 `"Hello"`。
- **布林值 (boolean)**:邏輯值 `True` 或 `False`。
- **列表 (list)**:有序的資料序列,如 `[1, 2, "Hello"]`。
- **字典 (dictionary)**:無序的鍵值對,如 `{"name": "Alice", "age": 25}`。
- **元組 (tuple)**:不可變的有序資料序列,如 `(10, 20)`。
- [**集合 (set)**](https://colab.research.google.com/drive/1aqdVRAmUEFKc_XxsUZfzeBe81Y91bNNH?usp=sharing):無序且唯一的資料集合,如 `{"a", "b"}`。
---
### <font size="5" color="red">[補充資料]</font>
在 Python 中,`&`、`|` 和 `and`、`or`、`not` 是不同的運算符,分別適用於**位運算**和**邏輯運算**。以下是它們的差異和用法:
### 1. `&`、`|`、`^`、`~` 等位運算符
位運算符通常用於**數字的二進位表示**,逐位(bitwise)進行操作。它們作用於整數,直接操作其二進位表示。
| 符號 | 操作 | 說明 |
|------|------|-----------------------------------|
| `&` | 位元 AND | 對應位元都為 1,結果才為 1 |
| `|` | 位元 OR | 只要對應位元有一個為 1,結果就為 1 |
| `^` | 位元 XOR | 對應位元不同則為 1,相同則為 0 |
| `~` | 位元 NOT | 對位元取反 |
#### 例子
```python
a = 6 # 二進位為 110
b = 3 # 二進位為 011
print(a & b) # 結果為 2(二進位 010)
print(a | b) # 結果為 7(二進位 111)
print(a ^ b) # 結果為 5(二進位 101)
print(~a) # 結果為 -7(因為 ~6 = -7)
```
### 2. `and`、`or`、`not` 邏輯運算符
這些是**邏輯運算符**,用於布林值(`True` 和 `False`)的邏輯操作,也可以用於其他非數值類型,Python 會根據其「真假性」來進行運算。
| 符號 | 操作 | 說明 |
|--------|-------|-----------------------------------|
| `and` | 邏輯 AND | 兩者都為 `True` 時才為 `True` |
| `or` | 邏輯 OR | 只要有一個為 `True`,結果就為 `True` |
| `not` | 邏輯 NOT | 反轉布林值,`True` 變 `False`,`False` 變 `True` |
#### 例子
```python
x = True
y = False
print(x and y) # 結果為 False
print(x or y) # 結果為 True
print(not x) # 結果為 False
```
### 總結
- **`&`、`|` 等位運算符**:處理二進位的逐位操作。
- **`and`、`or`、`not`**:用於邏輯運算,基於布林值進行操作。
---
### <font size="5" color="red">[補充資料]</font>關於使用 eval() 和 ast.literal_eval() 自動判別資料型態的詳細筆記
- 1. **`eval()` 函數**
`eval()` 是一個內建函數,能夠解析和運行傳遞給它的字串作為 Python 表達式。因此,當你從 `input()` 接收到字串時,可以使用 `eval()` 來將該字串轉換為對應的資料型態。
- **優點:**
- `eval()` 可以自動將字串轉換成相應的資料型態,如整數、浮點數、列表、字典等。
- 它可以處理複雜的 Python 表達式(如數學運算、列表操作等)。
- **缺點:**
- **安全性問題**:`eval()` 會執行字串中的任何 Python 代碼,這可能導致安全隱患。如果使用者輸入惡意代碼,可能會造成危害。
- **範例說明:**
```
import os
lis = os.listdir()
print(eval(input(f"test: ")))
```
```python
user_input = input("Enter something: ") # 假設輸入為 '3 + 4'
converted_input = eval(user_input)
print("資料型態:", type(converted_input)) # 會顯示 <class 'int'>
print("結果:", converted_input) # 輸出: 7
```
- **詳細說明:**
- `input()` 會將使用者輸入的字串 `'3 + 4'` 讀入。
- 使用 `eval()` 函數時,這個字串會被當作 Python 表達式運算,結果是整數 `7`。
- `eval()` 的靈活性很高,可以處理數學運算、列表、字典等結構。
- **注意事項:**
由於 `eval()` 會執行字串中的代碼,使用者輸入可能包含惡意代碼,以下是危險範例:
```python
user_input = input("Enter something dangerous: ") # 如果輸入 'os.system("rm -rf /")' 可能會刪除系統文件
eval(user_input)
```
這樣的情況下,惡意代碼可能會被執行,對系統造成危害。
---
- 2. **`ast.literal_eval()` 函數**
`ast.literal_eval()` 是 Python 的抽象語法樹 (Abstract Syntax Trees) 模組中的一個安全版本的 `eval()`。它只能處理 **基本資料型態**(如整數、浮點數、字串、列表、元組、字典和布林值等),並且不會執行惡意代碼,從而避免安全隱患。
- **優點:**
- **安全性較高**:只處理基本的 Python 類型,避免了執行任意代碼的風險。
- 適合在需要安全地解析輸入數據時使用,尤其是來自不受信任的來源。
- **缺點:**
- 無法解析或運行複雜的 Python 表達式(例如數學運算或函數調用)。
- **範例說明:**
```python
import ast
user_input = input("Enter something: ") # 假設輸入 '[1, 2, 3]'
try:
converted_input = ast.literal_eval(user_input)
print("資料型態:", type(converted_input)) # 會顯示 <class 'list'>
print("結果:", converted_input) # 輸出: [1, 2, 3]
except (ValueError, SyntaxError):
print("輸入無效或不是可解析的類型")
```
- **詳細說明:**
- `input()` 讀取使用者輸入的字串 `'[1, 2, 3]'`。
- `ast.literal_eval()` 會將字串解析為對應的列表類型。
- 此方法安全地將資料轉換為對應的 Python 資料型態,如列表、字典、元組等。
- 如果輸入不是有效的基本資料型態,`literal_eval()` 會拋出 `ValueError` 或 `SyntaxError` 錯誤。
- **安全範例:**
```python
import ast
user_input = input("Enter something dangerous: ") # 即使輸入 'os.system("rm -rf /")'
try:
converted_input = ast.literal_eval(user_input)
print("資料型態:", type(converted_input))
except (ValueError, SyntaxError):
print("輸入無效或不是可解析的類型")
```
在這裡,即使使用者輸入惡意代碼,它也不會被執行,因為 `ast.literal_eval()` 只能處理字面值的類型,如字串、數字和基本結構。
---
- 3. **`eval()` 和 `ast.literal_eval()` 的比較**
| 特性 | `eval()` | `ast.literal_eval()` |
|------------------------|--------------------------------------|-----------------------------------------|
| **功能** | 解析和執行任何 Python 表達式 | 只能解析基本的 Python 資料型態 |
| **安全性** | 不安全,會執行任意代碼 | 安全,只處理基本類型,不會執行代碼 |
| **處理的資料型態** | 任意表達式、資料型態 | 整數、浮點數、字串、列表、元組、字典、布林值 |
| **適合情況** | 需要執行動態表達式 | 處理來自不受信任來源的資料 |
---
- 4. **何時選擇使用 `eval()` 或 `ast.literal_eval()`**
- **`eval()`** 適合在您完全信任使用者輸入並需要動態執行複雜表達式的情況下使用(例如,執行數學運算或調用函數)。
- **`ast.literal_eval()`** 適合在安全性是首要考量時使用,尤其是在處理不受信任的輸入時,這樣可以避免執行潛在的惡意代碼。
---
- 5. **總結:**
- `eval()` 雖然功能強大,但有潛在的安全風險。
- `ast.literal_eval()` 是更安全的選擇,適合大部分基本資料型態的轉換需求。
希望這份筆記能幫助您清楚了解 `eval()` 和 `ast.literal_eval()` 的差異及應用!
## 4. 數字與運算
- Python 支援的數字類型有 `integer` 和 `float`。
- **基本運算**:加法 `+`、減法 `-`、乘法 `*`、除法 `/`、餘數運算 `%` 和指數運算 `**`。
- 常見運算函數:
- `abs()`:求絕對值。
- `pow()`:指數運算,例如 `pow(2, 3)` 給出 `8`。
- `max()` / `min()`:找出一組數中的最大值或最小值。
- `round()`:四捨五入。
### <font size="5" color="red">[補充資料]</font> 四捨五入
- `round()` 函數,特別是為什麼 `2.5` 會被四捨五入到 `2` 而不是 `3`,這是因為 Python 採用了一種稱為「**銀行家捨入法**(rounding to even,也叫做四捨五入到最近的偶數)」的規則。
- ### 銀行家捨入法的規則:
- 當一個數字正好在兩個整數之間(例如 `2.5`、`3.5`),Python 的 `round()` 會將其四捨五入到最接近的偶數。這樣做是為了在大量的數據中,避免總是將 `.5` 四捨五入到相同方向而造成偏差。
- **如果四捨五入後的數字是偶數**,則會向偶數靠攏。
- **如果四捨五入後的數字是奇數**,則會向奇數靠攏。
- ### 例子:
- `round(2.5)` → 2(因為 2 是偶數)
- `round(3.5)` → 4(因為 4 是偶數)
- `round(1.5)` → 2(因為 2 是偶數)
這種方法在統計上可以避免捨入誤差的累積,因此在許多金融和數據處理應用中更為精確。
- ### 結論:
- `round(2.5)` 之所以是 `2` 而不是 `3`,是因為 Python 使用了銀行家捨入法,將 `.5` 四捨五入到最接近的偶數。
- 根據 **銀行家捨入法** 的規則,如果遇到 `.5` 且整數位是偶數,那麼就不會進位,會直接保持該偶數。這樣做的目的是避免總是向上或向下捨入,從而減少捨入偏差。
- ### 規則回顧:
- 當 `.5` 遇到一個 **偶數**,則捨入結果保持該偶數。
- 當 `.5` 遇到一個 **奇數**,則捨入結果進位到下一個偶數。
- ### 例子:
- `round(2.5)` → 2(因為 2 是偶數,不進位)
- `round(3.5)` → 4(因為 3 是奇數,進位到 4)
- `round(4.5)` → 4(因為 4 是偶數,不進位)
- `round(5.5)` → 6(因為 5 是奇數,進位到 6)
- 這個規則適用於所有 `.5` 結尾的數字。如果整數位是偶數,則保持不變;如果是奇數,則進位到最近的偶數。這種方式可以在大量數據的捨入運算中均衡誤差分布。
## 5. 函數 (Function)
- **函數 (Function)** 是 Python 中的重要概念,類似於數學中的函數,輸入一個值並返回一個結果。
- Python 的內建函數 (built-in functions) 可以不帶輸入值,也可以有輸入值,但只會返回一個輸出。
### <font size="5" color="red">[補充資料]</font>**函數 (function)** 和 **方法 (method)** 的補充說明:
---
- ### Python 中函數 (Function) 與方法 (Method) 的差異
- ## 1. 函數 (Function)
- ### 定義:
- 函數是可以重複使用的代碼片段,它執行特定任務,可以接受參數並返回結果。
- 函數是全局的,與任何特定物件或類別無關。
- ### 語法:
```python
def function_name(parameters):
# 函數內容
return result
```
- ### 範例:
```python
def greet(name):
return f"Hello, {name}!"
message = greet("Alice")
print(message) # 輸出: Hello, Alice!
```
- ### 詳細說明:
- `greet()` 是一個全局函數,接受參數 `name` 並返回一個字串作為結果。
- 可以在代碼的任何地方調用這個函數,而不依賴於物件或類別。
- ### 特性:
- 函數是全局的,與物件或類無關。
- 函數可以接收參數並返回結果,但不需要與物件交互。
---
- ## 2. 方法 (Method)
- ### 定義:
- 方法是定義在類別中的函數,它只能通過類別的實例(物件)來調用,並且通常用來操作或訪問物件的屬性。
- 方法的第一個參數通常是 `self`,代表方法所屬的物件。
- ### 語法:
```python
class MyClass:
def method_name(self, parameters):
# 方法內容
return result
```
- ### 範例:
```python
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}!"
person = Person("Bob")
message = person.greet()
print(message) # 輸出: Hello, Bob!
```
- ### 詳細說明:
- `greet()` 是定義在 `Person` 類別中的方法,必須通過 `Person` 的物件來調用。
- 方法的第一個參數 `self` 代表當前物件,它允許方法訪問和修改物件的屬性(如 `self.name`)。
- ### 特性:
- 方法必須通過物件調用,並且與類或物件相關聯。
- 方法可以訪問物件的屬性,並與物件的狀態緊密相關。
---
- ## 3. 函數與方法的比較
| 特性 | 函數 (Function) | 方法 (Method) |
| -------------- | ------------------------------------------ | ------------------------------------------ |
| **定義位置** | 全局,獨立於類別 | 類別內,與物件相關聯 |
| **調用方式** | 直接調用,與物件無關 | 必須通過物件調用 |
| **第一個參數** | 無需 `self` 參數 | 第一個參數必須是 `self`,表示當前物件 |
| **關聯性** | 與任何物件無關 | 與物件或類別緊密相關 |
| **使用場景** | 適合處理不依賴物件的邏輯 | 適合操作或修改物件狀態的操作 |
---
- ## 4. 具體範例對比:函數 vs. 方法
- ### 函數範例:
```python
def add_numbers(a, b):
return a + b
result = add_numbers(3, 4)
print(result) # 輸出: 7
```
- #### 說明:
- `add_numbers()` 是一個全局函數,它接受兩個參數 `a` 和 `b`,然後返回它們的和。這個函數不依賴於任何物件或類別。
- ### 方法範例:
```python
class Calculator:
def add(self, a, b):
return a + b
calc = Calculator()
result = calc.add(3, 4)
print(result) # 輸出: 7
```
- #### 說明:
- `add()` 是定義在 `Calculator` 類別中的方法,它只能通過 `Calculator` 物件(`calc`)來調用。這個方法使用 `self` 參數來表示當前物件。
---
- ## 5. 何時使用函數與方法
- ### 使用 **函數** 的情況:
- 當操作不依賴於物件時,應使用全局函數。例如,處理純數據操作、數學運算等。
- ### 使用 **方法** 的情況:
- 當操作需要訪問或修改物件的屬性,或與物件的狀態相關聯時,應使用方法。
---
- ## 6. 總結
- **函數** 是全局代碼,可以在任何地方調用,適合獨立於類或物件的邏輯操作。
- **方法** 是屬於物件的函數,必須通過物件調用,適合處理與物件相關的操作與狀態變化。
- 函數和方法的應用場景不同,理解它們的差異有助於編寫更有組織和結構的代碼。
## 6. 字串操作
- **有序性**:字串中的字元是有順序的,可以使用 **索引 (indexing)** 和 **切片 (slicing)** 來存取字元。
- 例如:`"Hello"[1]` 會返回 `"e"`。
- **字串連接**:用 `+` 連接兩個字串,如 `"Hello" + "World"` 會得到 `"HelloWorld"`。
- **不可變性**:字串無法直接修改,任何操作都會返回一個新字串。
### <font size="5" color="red">[補充資料]</font>關於字串使用三重引號 (`"""` 或 `'''`)、雙引號 (`""`) 和單引號 (`''`) 的技巧應用:
---
- ### Python 字串中的雙引號 (`""`) 和單引號 (`''`)
在 Python 中,字串可以用雙引號 (`""`) 或單引號 (`''`) 表示。兩者在大多數情況下是等效的,但在某些應用場景中,它們各自有不同的使用技巧和優勢。
---
- ## 1. **基本使用**
Python 中,無論使用雙引號還是單引號,都可以定義字串:
- 使用雙引號:
```python
string1 = "Hello, World!"
print(string1) # 輸出: Hello, World!
```
- 使用單引號:
```python
string2 = 'Hello, World!'
print(string2) # 輸出: Hello, World!
```
- 詳細說明:
- `""` 和 `''` 都能夠表示字串,兩者在基本的字串表示上沒有區別。
---
- ## 2. **避免字串中的引號衝突**
當字串中需要包含引號時,雙引號和單引號的選擇可以幫助避免使用轉義字符。這是它們之間最常見的技巧之一。
- ### 在字串中使用單引號:
當字串中需要使用單引號時,可以將字串包裹在雙引號中,這樣就不需要使用轉義符:
```python
string1 = "It's a beautiful day!"
print(string1) # 輸出: It's a beautiful day!
```
- ### 在字串中使用雙引號:
反之,如果字串中需要使用雙引號,可以將字串包裹在單引號中:
```python
string2 = 'She said, "Hello!"'
print(string2) # 輸出: She said, "Hello!"
```
- ### 詳細說明:
- 通過選擇合適的引號包裹字串,可以避免不必要的轉義字符,使代碼更加易讀。
---
- ## 3. **使用轉義字符**
- 當需要在字串中包含與包裹字串的引號相同的符號時,可以使用反斜槓 (`\`) 來進行轉義。
- ### 在雙引號字串中使用雙引號:
```python
string1 = "He said, \"Python is awesome!\""
print(string1) # 輸出: He said, "Python is awesome!"
```
- ### 在單引號字串中使用單引號:
```python
string2 = 'It\'s a sunny day.'
print(string2) # 輸出: It's a sunny day.
```
- ### 詳細說明:
- 當雙引號和單引號的使用情境有衝突時,可以使用 `\` 來轉義這些引號,讓它們作為字串內容的一部分。
---
- ### 4. **多行字串的表示**
Python 提供了三重引號 (`"""` 或 `'''`) 來定義多行字串,這在長文本的輸入或格式化時非常有用。
- ### 使用三重雙引號:
```python
long_string = """This is a long string.
It spans multiple lines.
Isn't it cool?"""
print(long_string)
```
- ### 使用三重單引號:
```python
long_string = '''This is another long string.
It also spans multiple lines.
"Python" makes it easy.'''
print(long_string)
```
- ### 詳細說明:
- 當需要編寫多行字串時,三重引號可以避免使用繁瑣的換行符號或轉義字符,使代碼更加簡潔。
---
- ## 5. **嵌套引號的使用**
有時候,可能需要在字串中同時使用雙引號和單引號。這時可以結合使用雙引號、單引號和轉義字符來實現。
- ### 範例:
```python
nested_string = "He said, 'Python is \"awesome\" and easy to learn.'"
print(nested_string) # 輸出: He said, 'Python is "awesome" and easy to learn.'
```
- ### 詳細說明:
- 在字串中可以同時使用單引號和雙引號,並通過轉義來處理這些引號的嵌套。
---
- ## 6. **引號的一致性和最佳實踐**
在實際開發中,雙引號和單引號的選擇應該保持一致,以便提高代碼的可讀性和維護性。通常,團隊或專案會約定使用雙引號還是單引號,開發者應遵循這種約定。
- ### 範例:
- 如果團隊約定使用雙引號表示字串,那麼應該統一遵循此規範:
```python
string1 = "Hello, World!"
string2 = "Python is awesome!"
```
---
- ## 7. **總結**
- **雙引號 (`""`) 和單引號 (`''`) 在大多數情況下是等價的**,都可以用來定義字串。
- **選擇適當的引號來避免轉義字符**:當字串內包含單引號時,使用雙引號包裹字串;反之亦然。
- **轉義字符** (`\`) 可以在需要時插入與包裹字串相同的引號。
- **多行字串** 可以使用三重引號 (`"""` 或 `'''`) 來定義,方便長文本的處理。
- **嵌套引號** 可以同時使用雙引號和單引號,並使用轉義字符來解決衝突。
- 最好根據專案或團隊規範來選擇一致的引號表示法,以提高代碼的一致性和可讀性。
這些技巧可以幫助在 Python 中靈活運用雙引號與單引號,並根據不同的需求選擇最佳解決方案。
## 7. 列表 (List) 操作
- **列表 (list)** 是有序且可變的資料序列,如 `[1, 2, 3]`。
- 常見列表操作方法:
- `append()`:在列表末尾添加元素。
- `remove()`:移除指定元素。
- `sort()`:對列表進行排序。
- `reverse()`:反轉列表順序。
## 8. 字典 (Dictionary) 操作
- **字典 (dictionary)** 是無序的鍵值對,如 `{"name": "Alice", "age": 25}`。
- 常見字典操作方法:
- `keys()`:返回所有鍵。
- `values()`:返回所有值。
- `items()`:返回所有鍵值對。
## 9. 元組 (Tuple) 與集合 (Set)
- **元組 (tuple)** 是不可變的有序資料序列,如 `(1, 2, 3)`。
- **集合 (set)** 是無序且唯一的資料集合,常用於數學集合運算。
## 10. 變數與賦值 (Variable and Assignment)
- **變數 (variable)** 是存儲資料的容器,可以使用等號 `=` 來進行賦值。
- 例如:`x = 5`,表示將 `5` 賦值給變數 `x`。
- Python 的等號 `=` 是 **賦值 (assignment)**,而非數學中的等於。
## 11. 註解 (Comments)
- 使用 `#` 來添加註解,這是 Python 程式碼的良好習慣,方便理解程式邏輯。
## 12. 額外概念
- **Typecasting**:在 Python 中,可以使用 `int()`、`float()` 和 `str()` 來轉換資料型態。
- 例如:`int("3")` 會將字串 `"3"` 轉換為整數 `3`。
這些筆記涵蓋了Python基礎語法與資料型態,為進階學習打下基礎。
以下是基於您提供的上下文和Python課程的內容,整理的Chapter 2的目錄及摘要,最後附上總結心得筆記。
# Chapter 2 目錄及摘要
## 1. **Python運算符**
- 運算符的定義:用於操作數據的符號。
- 主要運算符類型:
- 算術運算符
- 比較運算符
- 邏輯運算符
- 其他運算符(如位元運算符、身份運算符)
## 2. **算術運算符**
- 加法 (+):
```python
result = 4 + 5 # result 為 9
```
- 減法 (-):
```python
result = 10 - 3 # result 為 7
```
- 乘法 (*):
```python
result = 2 * 3 # result 為 6
```
- 除法 (/):
```python
result = 10 / 2 # result 為 5.0
```
- 餘數 (%):
```python
result = 10 % 3 # result 為 1
```
- 指數 (**):
```python
result = 2 ** 3 # result 為 8
```
## 3. **比較運算符**
- 用於比較兩個值,返回布林值。
- 常見比較運算符:
- 等於 (==):`result = (5 == 5) # result 為 True`
- 不等於 (!=):`result = (5 != 3) # result 為 True`
- 大於 (>):`result = (10 > 5) # result 為 True`
- 小於 (<):`result = (5 < 10) # result 為 True`
- 大於等於 (>=):`result = (5 >= 5) # result 為 True`
- 小於等於 (<=):`result = (3 <= 2) # result 為 False`
## 4. **指派運算符**
- 用於將值賦予變數。
- 基本指派 (=):`x = 10 # x 的值為 10`
- 簡化指派 (+=):`x += 5 # x 現在為 15`
- 簡化指派 (-=):`x -= 3 # x 現在為 12`
- 簡化指派 (*=):`x *= 2 # x 現在為 24`
- 簡化指派 (/=):`x /= 4 # x 現在為 6.0`
## 5. **邏輯運算符**
- 用於組合布林運算。
- 主要運算符:
- and:`result = (True and False) # result 為 False`
- or:`result = (True or False) # result 為 True`
- not:`result = not True # result 為 False`
## 6. **真值和假值**
- 在布林上下文中,幾乎所有Python對象都可以評估為真或假。
- 假值包括:
- 空列表:`[]` → `bool([]) # 為 False`
- 空字串:`""` → `bool("") # 為 False`
- 零:`0` → `bool(0) # 為 False`
- None:`bool(None) # 為 False`
- False:`bool(False) # 為 False`
- 真值包括:
- 非空序列或集合:`[1, 2]` → `bool([1, 2]) # 為 True`
- 非零數值:`5` → `bool(5) # 為 True`
- True:`bool(True) # 為 True`
## 7. **短路評估**
- 短路評估的概念和使用場景。
- 例如:`if True and (1 / 0): # 不會執行 (1 / 0)`,因為前面的條件已經確定為 True。
### 總結心得筆記
在Chapter 2中,我們深入探討了Python中的運算符及其應用,這些運算符是編程中不可或缺的部分。理解它們的功能和用法將有助於編寫高效且易於維護的代碼。此外,真值和假值的概念讓我們能夠更好地控制程式的邏輯流,而短路評估則提供了一種優化性能的方式。
透過這一章的學習,我更加熟悉了Python語言的基本運算和邏輯結構,這些知識不僅適用於Python,對於其他編程語言的學習也有很大的幫助。未來的學習中,我希望能將這些運算符與更複雜的程式結構結合起來,實現更具功能性的應用程式。
# Chapter3 控制流程 (Control Flow)
## 1. 控制流程 (Control Flow)
- **定義**: 控制程式碼的執行順序,以及根據條件決定哪些程式碼要執行。
- **主要概念**: `if` 陳述式。
- **範例**:
```python
age = 18
if age >= 18:
print("你是成年人")
else:
print("你是未成年人")
```
## 2. 迴圈 (Loops)
- **定義**: 用於重複執行某段程式碼,直到達到特定條件。
- **種類**:
- **for 迴圈**: 遍歷序列(如列表、字串等)。
- **範例**:
```python
for i in range(5):
print(i) # 輸出: 0 1 2 3 4
```
- **while 迴圈**: 在條件為真的情況下重複執行。
- **範例**:
```python
count = 0
while count < 5:
print(count)
count += 1 # 輸出: 0 1 2 3 4
```
## 3. 函式 (Functions)
- **定義**: 將一段程式碼封裝起來,使其可以重複使用。
- **定義函式**: 使用 `def` 關鍵字定義自己的函式。
- **範例**:
```python
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 輸出: 8
```
## 4. 邏輯運算子 (Logical Operators)
- **and**: 只有當兩個操作數都為真時,結果才為真。
- **範例**:
```python
a = True
b = False
print(a and b) # 輸出: False
```
- **or**: 只要有一個操作數為真,結果就為真。
- **範例**:
```python
print(a or b) # 輸出: True
```
- **not**: 反轉操作數的布林值。
- **範例**:
```python
print(not a) # 輸出: False
```
## 5. 真值與假值 (Truthy and Falsy Values)
- **定義**: 在布林上下文中,幾乎所有 Python 物件都能被評估為真或假。
- **假值的範例**:
- 空列表 `[]`
- 空字典 `{}`
- 空字串 `""`
- 數字 0 (例如 `0`, `0.0`)
- **範例**:
```python
empty_list = []
if not empty_list:
print("這是一個空列表") # 輸出: 這是一個空列表
```
- **真值的範例**: 非空的序列或集合、非零的數字、布林值 True。
## 6. 短路評估 (Short-Circuit Evaluation)
- **定義**: 當一個表達式的結果已經確定時,評估會停止。
- **範例**:
```python
a = 2
if a or (10 / 0): # 此行不會被執行
print("a 是真值") # 輸出: a 是真值
```
### 總結
本課程涵蓋了 Python 的基本控制流程、回圈、函式、邏輯運算子、真值與假值的概念,以及短路評估的原理。透過實際範例,學生能夠理解並應用這些概念於實際的程式設計中。
# <font size="5" color="red">[讀書筆記]</font> - Python 第四章:Functions and Methods
## 目錄
### 1. Functions 和 Methods 的差別
- **差異點**:
- **Function**:不與物件相關聯,可直接調用,例如 `range()`
- **Method**:與物件相關聯,需透過物件調用,例如 `string.split()`
- **定義自訂函式的要點**:
- 使用 `def` 關鍵字。
- 定義的參數可為必選或可選(預設值)。
- 可使用 `return` 關鍵字返回值。
- 利用 Docstring 為函式添加說明,便於調用者理解。
2. 如何處理未曾見過的函數或方法
3. `def` 關鍵字與函數定義
4. `return` 關鍵字
5. Import Functions
6. Arguments 類型:Positional 與 Keyword
#### Inputs 與 Outputs 的設計
- **參數類型**:
- **Positional Arguments**:按位置傳遞參數。
- **Keyword Arguments**:以鍵值對形式傳遞參數。
- **可變參數**:使用 `*args` 與 `**kwargs` 接收不定數量的參數。
- **返回值**:
- 函式中可以選擇返回任何類型的值,包括 `string`、`tuple` 或其他物件。
- 若未指定返回值,預設為 `None`。
7. 預設參數 (Default Arguments)
8. 任意數量的參數 (Arbitrary Number of Arguments)
9. 高階函數 (Higher-Order Functions)
10. Lambda 表達式 (Lambda Expression)
### 為什麼 `lambda` 無法使用 `return`?
- **`lambda` 是一種匿名函數**,設計為簡短的單行表達式,語法上不允許使用多行語句或 `return` 關鍵字。
- **`lambda` 的結果是隱式返回的**:
- `lambda` 函數執行的表達式,其計算結果會自動作為返回值。
---
### 如果需要 `return`,可以改用普通函數:
如果需要明確地使用 `return`,應該使用 `def` 定義的函數。例如:
```python
def add(a, b):
for i in range(a):
for j in range(b):
if not (i == 2 and j == 1):
print(i, j)
return None # 明確返回
```
---
### 用 `lambda` 的方式實現類似效果:
雖然不能直接使用 `return`,但可以通過以下方式模擬 `return` 的效果:
#### 方式 1:`lambda` 搭配條件語句
```python
add = lambda a, b: [(print(i, j)) for i in range(a) for j in range(b) if not (i == 2 and j == 1)]
# 接收輸入
a = int(input("請輸入 a 的值:"))
b = int(input("請輸入 b 的值:"))
# 執行函數
add(a, b)
```
### 說明:
1. **`lambda` 函數**:
- 使用 `lambda` 定義匿名函數 `add`,接受參數 `a` 和 `b`。
- 使用列表推導式進行迴圈和條件篩選,模擬原函數邏輯。
2. **`input` 接收用戶輸入**:
- 透過 `input()` 獲取用戶輸入的 `a` 和 `b`,並轉換為整數型別。
3. **執行函數**:
- 呼叫 `add(a, b)`,使用輸入值進行運算並打印結果。
執行時,會提示用戶輸入兩個數值,然後列印符合條件的 `(i, j)` 配對組合。
#### 方式 2:將邏輯放在其他函數中
```python
def process(a, b):
for i in range(a):
for j in range(b):
if not (i == 2 and j == 1):
print(i, j)
return None
add = lambda a, b: process(a, b)
a, b = map(int, input("請輸入 a 和 b 的值(以空格分隔):").split())
add(a, b)
```
---
### **建議**
- 如果需要多行邏輯(如 `return`、`for` 等),**使用普通函數更合適**,因為 `lambda` 是為簡單表達式設計的,不適合處理複雜的邏輯。
- 如果只是進行簡單計算或篩選,`lambda` 是不錯的選擇。
11. 變數的作用域 (Scope)
#### Local 與 Global Variables
- **Local Variables**:
- 僅在函式內部有效,定義在函式中的變數。
- 不會影響函式外部的同名變數。
- **Global Variables**:
- 定義在函式外部,作用域遍及整個腳本。
- 需用 `global` 關鍵字在函式內修改。
12. 函數也是物件 (Functions are Objects)
13. 函式相關實作技巧
- **代碼示範**:
- 利用 `help()` 查看函式說明。
- 善用內建函式如 `enumerate` 提高程式可讀性。
- 使用 `import` 來引入標準庫或第三方模組,根據需求載入功能模組。
- **Debug 建議**:
- 使用 IDE 或 Python 的除錯工具(如 PDB)追蹤函式執行流程。
- 在函式內添加適當的錯誤處理機制,避免未處理的例外。
## 章節摘要
### 1. Functions 和 Methods 的差別
- **Functions** 是獨立的,可以由名稱直接調用。
- **Methods** 是與類別的物件相關聯的。
- 範例:
```python
# Function example
result = range(10)
# Method example
text = "How are you"
words = text.split()
```
### 2. 如何處理未曾見過的函數或方法
- 使用 `help()` 函數來獲取說明。
- 查閱官方文件。
### 3. `def` 關鍵字與函數定義
- 使用 `def` 來定義函數。
- 範例:
```python
def greet(name):
return f"Hello, {name}!"
```
### 4. `return` 關鍵字
- 用於結束函數並將值返回給主程序。
- 範例:
```python
def add(a, b):
return a + b
```
### 5. Import Functions
- 需要先使用 `import` 將某些函數或模組引入才能使用。
- 範例:
```python
from math import pi
```
### 6. Arguments 類型:Positional 與 Keyword
- **Positional Arguments** 必須按正確順序給定。
- **Keyword Arguments** 使用關鍵字和等號給定,順序可以不固定。
- 範例:
```python
def greet(name, age):
return f"{name} is {age} years old."
greet(age=25, name='Alice')
```
### 7. 預設參數 (Default Arguments)
- 函數可以有預設參數值。
- 範例:
```python
def greet(name, age=18):
return f"{name} is {age} years old."
```
### 8. 任意數量的參數 (Arbitrary Number of Arguments)
- 使用 `*args` 和 `**kwargs` 接受任意數量的參數。
- 範例:
```python
def add(*numbers):
return sum(numbers)
```
### 9. 高階函數 (Higher-Order Functions)
### **高階函數的定義**
在 Python 中,高階函數是一種 **接受其他函數作為參數** 或 **返回一個函數作為結果** 的函數。它們使 Python 支援函數式編程,提供更靈活的邏輯處理方式。
#### **關鍵特性**:
1. **函數作為參數**:可以將函數傳遞給高階函數進行處理。
2. **函數作為返回值**:高階函數可以返回一個新函數,形成閉包(Closure)。
3. **結合匿名函數(Lambda)**:常用匿名函數來實現高階函數的邏輯。
---
### **常見的高階函數**
Python 中幾個內建的高階函數包括:
- **`map()`**:對可迭代物件中的每個元素應用指定的函數。
- **`zip()`**:用於將多個可迭代物件(例如清單、元組等)「壓縮」成對應元素的組合,並以一個 迭代器 的形式返回。
- **`filter()`**:篩選出符合條件的元素。
- **`reduce()`**(需要從 `functools` 模組導入):對可迭代物件中的元素進行累積操作。
- **`sorted()`**:支持自定義排序條件的函數。
---
### **範例**
以下是幾個示例,展示高階函數的功能:
#### **1. 函數作為參數**
```python
def apply_function(func, value):
return func(value)
# 定義簡單的函數
def square(x):
return x * x
# 使用高階函數
result = apply_function(square, 5)
print(result) # 輸出: 25
```
#### **2. 函數作為返回值**
```python
def power_function(exponent):
def power(base):
return base ** exponent
return power
# 創建一個平方的函數
square = power_function(2)
print(square(3)) # 輸出: 9
# 創建一個立方的函數
cube = power_function(3)
print(cube(2)) # 輸出: 8
```
#### **3. 使用內建的高階函數**
##### **(a) `map()`**
```python
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)
print(list(squared)) # 輸出: [1, 4, 9, 16, 25]
```
##### **`zip()` 將 list1 和 list2 list3 的對應元素組成元組,生成一個新結構。**
```python
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
list3 = [True, False, True]
result = zip(list1, list2, list3)
print(list(result))
```
---
```python
zipped = [(1, 'a', True), (2, 'b', False), (3, 'c', True)]
list1, list2 ,list3 = zip(*zipped)
print(list1) # (1, 2, 3)
print(list2) # ('a', 'b', 'c')
print(list3) # (True,False,True)
```
##### **(b) `filter()`**
```python
numbers = [1, 2, 3, 4, 5]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers)) # 輸出: [2, 4]
```
##### **(c) `reduce()`**
```python
from functools import reduce
numbers = [1, 2, 3, 4, 5]
sum_of_numbers = reduce(lambda x, y: x + y, numbers)
print(sum_of_numbers) # 輸出: 15
```
##### **(d) `sorted()`**
```python
words = ["apple", "banana", "cherry"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words) # 輸出: ['apple', 'cherry', 'banana']
```
---
### **高階函數的應用場景**
1. **數據處理與轉換**:
- 使用 `map` 進行批量轉換。
- 使用 `zip`
1. **合併資料:**
- 常用於將兩個或多個清單合併為對應的元組結構。
2. **解壓縮資料:**
- 解壓縮結構化數據(例如從資料表中提取列)。
3. **遍歷多個可迭代物件:**
- 可以同時遍歷多個清單或結構,而不需要索引。
- 使用 `filter` 篩選數據。
2. **實現閉包和裝飾器(Decorator)**:
- 用於增強函數功能的設計模式。
3. **函數式編程風格**:
- 提升代碼的簡潔性與模組化程度。
---
以上是高階函數的詳述與應用示例及重要概念!
### 10. Lambda 表達式 (Lambda Expression)
- 匿名函數,通常用於短期的簡單函數。
- 範例:
```python
square = lambda x: x * x
```
### 11. 變數的作用域 (Scope)
- 使用 LEGB 規則來決定變數的範圍:Local, Enclosing, Global, Built-in。
- 範例:
```python
def outer():
x = "local"
def inner():
print(x)
inner()
```
### 12. 函數也是物件 (Functions are Objects)
- 函數能被賦值給其他變數。
- 範例:
```python
def greet():
print("Hello!")
say_hello = greet
say_hello()
```
### 特殊部份
嚴格來說,**`enumerate`** 不是典型的高階函數(Higher-Order Function),雖然它的使用方式和特性在某些情況下與高階函數類似。
---
### **為什麼 `enumerate` 不是高階函數?**
- **高階函數的定義**:
1. 接受函數作為參數,或
2. 返回一個函數作為結果。
- **`enumerate` 的行為**:
- 它不接受函數作為參數,也不返回函數。
- 它是一個內建函數,返回一個可迭代的 `enumerate` 對象,每個元素是 `(索引, 值)` 的元組。
因此,從功能上看,`enumerate` 只是提供了一個便捷的方式來對可迭代對象進行索引迭代,而不是高階函數。
---
### **`enumerate` 的特性**
- **輸入**:一個可迭代對象(如列表、元組、字串等)。
- **輸出**:一個迭代器,生成 `(索引, 值)` 的元組。
- **用途**:結合索引與值進行迭代操作。
---
### **範例:`enumerate` 的使用**
```python
# 基本用法
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 輸出:
# 0: apple
# 1: banana
# 2: cherry
# 自定義起始索引
for index, fruit in enumerate(fruits, start=1):
print(f"{index}: {fruit}")
# 輸出:
# 1: apple
# 2: banana
# 3: cherry
```
---
### **與高階函數的對比**
高階函數如 `map` 和 `filter` 可以接受函數作為參數,以下對比說明差異:
#### **`map` 範例**
```python
fruits = ['apple', 'banana', 'cherry']
upper_fruits = map(lambda x: x.upper(), fruits)
print(list(upper_fruits))
# 輸出: ['APPLE', 'BANANA', 'CHERRY']
```
#### **`enumerate` 無法接受函數**
`enumerate` 不會對其內部的元素應用函數,僅生成索引和值。
---
### **總結**
- **`enumerate`** 的作用是輔助索引和值的迭代,功能與高階函數不同。
- 它不接受函數作為參數,也不返回函數,因此並不屬於高階函數。
- 它是一個非常實用的工具,但需與高階函數(如 `map`、`filter`)區分。
這些是 Python 第四章中涉及的主要概念和範例,幫助理解函數和方法的用法及其重要性。
---
# <font size="10" color="ligreen">[讀書筆記]</font>
#### Chapter 4.5. Miscellaneous Information
#### 目錄
1. **Python Naming Restriction**
- 變數命名規則
- 保留字與特殊符號限制
2. **Python Naming Convention**
- 模組、函數、變數、類別、變數的命名慣例
3. **Pythonic**
- Pythonic 的意義與實踐
4. **Zen of Python**
- Python 之禪的概述
---
1. **Python Naming Restriction**
- **變數命名規則**:
- 必須以字母或下劃線開頭。
- 只能包含字母、數字和下劃線。
- 名稱區分大小寫。
- **保留字與特殊符號限制**:
- 不可使用 Python 的保留字。
- 不可包含特殊符號。
**範例**:
```python
# 正確的變數命名
player_score = 100
_player = "John"
# 錯誤的變數命名
# 1player = "Alice" # 不能以數字開頭
# player-score = 50 # 不能使用特殊符號
```
2. **Python Naming Convention**
- **模組名稱**:`my_module`
- **函數名稱**:`calculate_sum()`
- **變數名稱**:`user_name`
- **類別名稱**:`UserProfile`
- **常數名稱**:`MAX_LIMIT`
**範例**:
```python
# 模組名稱
import my_module
# 函數名稱
def calculate_sum(a, b):
return a + b
# 類別名稱
class UserProfile:
def __init__(self, name):
self.name = name
```
3. **Pythonic**
- 描述了一種撰寫 Python 程式的哲學,旨在提高程式碼的可讀性和清晰度。
- 強調使用 Python 的內建特性和標準函數來達成簡潔的程式設計。
**範例**:
```python
# Pythonic 的範例:列表推導式
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
```
4. **Zen of Python**
- Python 之禪由 19 條原則組成,用以指導 Python 的設計與實踐。
- 可以通過 `import this` 在 Python 解釋器中查看。
**範例**:
```python
import this # 查看 Python 之禪
```
---
這些筆記強調了命名規範的重要性,如何撰寫 Pythonic 的程式碼,以及 Python 之禪在程式設計中的應用。這些概念有助於撰寫更具可讀性和可維護性的程式碼。
### <font size="5" color="red">[補充資料]</font>Miscellaneous Information
在 Python 課程的 Chapter 4.5 中,補充了一些關於 Python 程式設計的補充資訊,
這些資訊雖然不是程式設計的核心,但對於提升程式碼的可讀性和維護性相當重要。
#### Python Naming Restriction - Python 命名限制
1. **變數命名規則**:
- 變數名稱必須以字母或底線(_)開始。例如,`_player_1` 或 `player_1` 是合法的,但 `1_player` 不是。
- 變數名稱只能包含字母、數字和底線,且必須遵循上述規則。
- 變數名稱是區分大小寫的。
- 不可使用保留字(例如 `int`, `list` 等)作為變數名稱,因為這些字在 Python 中具有特殊意義。
- 列出所有保留字
```python
import keyword
print(keyword.kwlist)
# 判斷某個單詞是否是保留字
print(keyword.iskeyword("if")) # True
print(keyword.iskeyword("variable")) # False
```
- 不可使用特殊符號如 `""/?|\()!@~+#`,這些符號在 Python 中有特殊用途。
#### Python Naming Convention - Python 命名慣例
Python 有一些命名慣例用於提高程式碼的可讀性:
- **模組名稱**:全部小寫,必要時使用底線分隔(例如 `my_module`)。
- **函數名稱**:全部小寫,必要時使用底線分隔(例如 `calculate_sum()`)。
- **變數名稱**:全部小寫,必要時使用底線分隔(例如 `MAX_LIMIT`)。
- **類別名稱**:首字母大寫,使用 CamelCase(例如 `MyClass`)。
- **變數名稱**:全部使用大寫字母,必要時使用底線分隔(例如 `MAX_VALUE`)。
#### Pythonic - Pythonic 編程風格
Pythonic 是一種描述用以符合 Python 程式設計語言創始哲學的方法的形容詞。
儘管在 Python 中有多種方式完成同一項任務,但通常有一種首選的方法——這被稱為 Pythonic。
撰寫 Pythonic 的程式碼意味著確保程式碼可讀、清晰、易於理解,並充分利用 Python 的特性和內建函數。
- **Pythonic 定義**:
- 符合 Python 核心哲學,追求簡潔與清晰。
- 善用 Python 的內建功能與特性來編寫高效代碼。
- **Pythonic 編程風格** 強調以下原則:
- **可讀性**(Readability Counts)
- **簡單性**(Simple is Better than Complex)
- **優雅性**(Explicit is Better than Implicit)
[語法糖](https://hackmd.io/@2YdnUWD8RpK3RWxZlSeg8Q/BkHngbzQkg)符合這些原則,因為它讓程式碼的結構更簡單、可讀性更高,因此可以說語法糖是 Pythonic 編程風格的體現之一。
- **核心原則**:
- 明確優於含糊。
- 簡單勝於複雜,複雜勝於難解。
- 可讀性至關重要。
- 特例不足以破壞規則,實用性勝於純粹性。
- 現在勝於永不,雖然永不有時優於立刻。
- **如何編寫 Pythonic 代碼**:
- 減少重複與冗長。
- 利用條件表達式、迭代器及生成器簡化邏輯。
- 確保代碼可讀性與易理解性。
#### Zen of Python - Python 之哲學
Python 之哲學是用於撰寫計算機程式的 19 條“指導原則”集合,這些原則影響了 Python 程式語言的設計。
由軟體工程師 Tim Peters 在 1999 年發表於 Python 郵件列表中。它也作為一個彩蛋包含在 Python 解釋器中,可以通過輸入 `import this` 來顯示。
這些補充資訊提供了撰寫 Python 程式時的最佳實踐指南,對於撰寫易於維護和理解的程式碼至關重要。
---
### <font size="5" color="red">[高階函數補充資料]</font>
高階函數的整理與說明,富有條理且涵蓋了實用範例,適合作為學習和教學的參考資料。
## 高階函數簡表
| 函數名 | 功能簡介 | 備註 |
|--------------------|-------------------------------------------|----------------------|
| `map` | 將函數應用於可迭代物件中的每個元素 | 返回迭代器 |
| `filter` | 過濾符合條件的元素 | 返回迭代器 |
| `reduce` | 累計計算,將函數應用於可迭代物件的元素 | 需導入 `functools` |
| `sorted` | 排序可迭代物件 | 可接受 `key` 參數 |
| `any` | 若至少有一個元素為真,返回 `True` | 布林檢查 |
| `all` | 所有元素都為真時返回 `True` | 布林檢查 |
| `zip` | 將多個可迭代物件按位置組合為元組 | 返回迭代器 |
| `enumerate` | 返回索引和元素 | 可設起始索引 |
| `lambda` | 匿名函數,用於簡化函數表達 | 善用於高階函數參數 |
| 函數作為返回值 | 返回一個內部定義的函數 | 允許動態生成功能 |
| `partial` | 固定函數部分參數,生成新函數 | `functools` 提供 |
| 裝飾器(Decorator)| 增強函數功能,保持原函數不變 | 增加靈活性 |
---
### 重點提示
1. **可讀性與簡潔性**:
- 高階函數能簡化代碼結構,讓代碼更具表達力。例如,`map` 和 `lambda` 結合可以大幅縮短處理數據的代碼長度。
2. **結合生成器和混合技巧**:
- `map`、`filter`、`zip` 等返回迭代器,避免了一次性生成大量數據帶來的性能問題。
3. **實用性建議**:
- 使用生活化的例子(例如處理清單、計算成績等)理解高階函數的作用。
- 強調 `key` 參數的靈活性,如在排序、篩選中的應用。
---
### 高階函數的應用場景
1. **數據處理**:
- 使用 `map` 和 `filter` 快速轉換和篩選數據。
2. **累積計算**:
- 使用 `reduce` 計算總和、最大值或自定義累積邏輯。
3. **函數組合**:
- `partial` 和返回函數功能,用於創建動態函數。
4. **功能拓展**:
- 使用裝飾器,為現有函數添加功能(如記錄日誌或檢查權限)。
---
# 高階函數整理與詳細說明
高階函數是指**接受函數作為參數**或**返回函數作為結果**的函數。在 Python 中,函數是一等公民,這使得高階函數的使用非常靈活與強大。以下是常見的高階函數介紹,包含範例和詳細說明。
## 高階函數範例與說明
### 1. **`map(function, iterable, ...)`**
**功能**:對可迭代物件中的每個元素應用指定的函數,返回一個迭代器。
**範例**:
```python
def square(x):
return x * x
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(square, numbers)
print(list(squared_numbers)) # 輸出:[1, 4, 9, 16, 25]
```
**解說**:`map` 將 `square` 函數應用於 `numbers` 列表的每個元素。
---
### 2. **`filter(function, iterable)`**
**功能**:根據函數的返回值對可迭代物件進行篩選,返回符合條件的元素迭代器。
**範例**:
```python
def is_even(x):
return x % 2 == 0
numbers = [1, 2, 3, 4, 5]
even_numbers = filter(is_even, numbers)
print(list(even_numbers)) # 輸出:[2, 4]
```
**解說**:`filter` 函數篩選出符合 `is_even` 條件的元素。
---
### 3. **`reduce(function, iterable[, initializer])`**
**功能**:對可迭代物件中的元素進行累積計算。
**範例**:
```python
from functools import reduce
def add(x, y):
return x + y
numbers = [1, 2, 3, 4, 5]
sum_numbers = reduce(add, numbers)
print(sum_numbers) # 輸出:15
```
**解說**:`reduce` 函數將 `add` 函數累積地應用於列表元素,計算總和。
---
### 4. **`sorted(iterable, key=None, reverse=False)`**
**功能**:返回排序後的新列表,可通過 `key` 參數自定義排序條件。
**範例**:
```python
words = ['apple', 'banana', 'cherry', 'date']
sorted_words = sorted(words, key=len)
print(sorted_words) # 輸出:['date', 'apple', 'banana', 'cherry']
```
**解說**:`sorted` 根據字符串長度對列表進行排序。
---
### 5. **`any(iterable)`**
**功能**:只要可迭代物件中有一個元素為真,返回 `True`。
**範例**:
```python
numbers = [0, 0, 1, 0]
print(any(numbers)) # 輸出:True
```
---
### 6. **`all(iterable)`**
**功能**:只有所有元素都為真時,返回 `True`。
**範例**:
```python
numbers = [1, 2, 3, 4]
print(all(numbers)) # 輸出:True
```
---
### 7. **`zip(*iterables)`**
**功能**:將多個可迭代物件按索引位置組合為元組,返回迭代器。
**範例**:
```python
letters = ['a', 'b', 'c']
numbers = [1, 2, 3]
zipped = zip(letters, numbers)
print(list(zipped)) # 輸出:[('a', 1), ('b', 2), ('c', 3)]
```
---
### 8. **`enumerate(iterable, start=0)`**
**功能**:為可迭代物件中的元素提供索引。
**範例**:
```python
items = ['apple', 'banana', 'cherry']
for index, value in enumerate(items, start=1):
print(index, value)
```
---
### 9. **`lambda` 函數**
**功能**:創建匿名函數,用於簡化函數表達式。
**範例**:
```python
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x * x, numbers)
print(list(squared_numbers)) # 輸出:[1, 4, 9, 16, 25]
```
---
### 10. **函數作為返回值**
**功能**:函數可以返回另一個函數,用於創建動態功能。
**範例**:
```python
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
times3 = make_multiplier(3)
print(times3(5)) # 輸出:15
```
---
### 11. **`functools.partial(func, *args, **keywords)`**
**功能**:固定函數的部分參數,生成新函數。
**範例**:
```python
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
print(square(5)) # 輸出:25
```
---
### 12. **裝飾器(Decorator)**
**功能**:接受函數作為參數,返回增強後的新函數。
**範例**:
```python
def logger(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@logger
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
```
---
## 總結
高階函數是**函數式編程**的核心工具,能讓代碼更簡潔、高效且易於維護。善用 Python 提供的高階函數,可以解決許多數據處理和邏輯操作的需求。同時,靈活使用 `lambda` 和裝飾器等功能,能顯著提升代碼的可讀性與重用性。
---
### <font size="5" color="red">[讀書筆記]</font>
# Chapter 6 - Object Oriented Programming
#### 物件導向程式設計 (OOP) 概述
- **定義與特性**:OOP 是一種編程範式,強調將資料和行為綁定到個體物件上。Python 中的 OOP 支持類別、繼承、多重繼承和封裝。
#### 類別與物件
- **類別 (Class)**:類別是創建物件的模板,定義了物件的屬性和方法。
- **物件 (Object)**:物件是類別的具體實例。
- **範例**:定義 `robot` 類別,並創建實例。
#### 初始化方法與自訂方法
- **`__init__` 方法**:用於初始化物件的屬性。
- **自訂方法**:定義物件的行為。
- **範例**:為 `robot` 定義 `walk` 和 `sleep` 方法。
#### 類別屬性與方法
- **類別屬性**:所有實例共享的屬性。
- **靜態方法與類別方法**:提供不同的使用場景。
- **範例**:使用 `circle` 類別計算圓的面積,定義靜態方法 `total_area`。
#### 繼承 (Inheritance)
- **繼承**:子類別可以繼承父類別的屬性和方法。
- **`super()` 函數**:用於調用父類別的方法。
- **範例**:`student` 繼承 `people` 類別,覆寫 `eat` 方法。
#### 多重繼承 (Multiple Inheritance)
- **概念**:允許從多個父類別繼承。
- **MRO (Method Resolution Order)**:方法解析順序,用於解決多重繼承中的潛在衝突。
- **範例**:定義多層次繼承結構,使用 `mro()` 方法檢查方法解析順序。
#### 封裝 (Encapsulation)
- **定義**:將資料和方法封裝在類別中,限制對內部狀態的直接訪問。
- **私有屬性與方法**:通過前置雙底線 `__` 來標識。
- **範例**:定義 `robot` 的私有屬性和方法。
#### Hash 函數
- **Python 內建的 Hash 函數**:將可 hash 的物件轉換為固定大小的整數。
- **用途與安全性**:提高資料結構查找效率和安全性。
- **範例**:對字串和其他 hashable 類型使用 hash 函數。
#### 安全性與最佳實踐
- **不可逆 (Not Invertible)**:為了安全目的,hash 函數不應該是可逆的。
- **加密與密碼學應用**:bcrypt、SHA256 等。
### 總結
這些筆記涵蓋了物件導向程式設計的基本概念及其在 Python 中的應用。透過類別與物件的創建、屬性和方法的管理,以及繼承與多重繼承的使用,學習者能夠編寫結構良好、可重用的程式碼。此外,對於 Python 特性如 hash 函數和安全性考量的理解也增強了程式設計的實用性和安全性。
---
基於 OOP 為設計基礎的 Python 程式範例說明:
---
### 類別與物件 (Classes and Objects)
```python
# 定義一個簡單的類別和物件
class Robot:
# 初始化方法,設定機器人的名稱
def __init__(self, name):
self.name = name
# 定義機器人的行為方法
def greet(self):
return f"Hello, my name is {self.name}."
# 創建 Robot 類別的實例
robot1 = Robot("Robo")
print(robot1.greet()) # 輸出: Hello, my name is Robo.
```
**說明**:這個範例展示了如何定義一個類別 `Robot`,以及如何創建物件並調用其方法。
---
### 初始化方法與自訂方法 (Init and Custom Methods)
```python
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def display_info(self):
return f"Car brand: {self.brand}, Model: {self.model}"
# 創建 Car 類別的實例
car1 = Car("Toyota", "Corolla")
print(car1.display_info()) # 輸出: Car brand: Toyota, Model: Corolla
```
**說明**:此範例展示了如何使用 `__init__` 方法初始化物件屬性,以及自訂方法 `display_info` 的使用。
---
### 類別屬性與方法 (Class Attributes and Methods)
```python
class Circle:
pi = 3.14159 # 類別屬性
def __init__(self, radius):
self.radius = radius
def area(self):
return Circle.pi * (self.radius ** 2)
# 創建 Circle 類別的實例並計算面積
circle1 = Circle(5)
print(circle1.area()) # 輸出: 78.53975
```
**說明**:這個範例展示了類別屬性 `pi` 的使用,以及如何計算圓的面積。
---
### 繼承 (Inheritance)
```python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
# 創建 Dog 類別的實例
dog1 = Dog("Buddy")
print(dog1.speak()) # 輸出: Woof!
```
**說明**:此範例展示了如何使用繼承讓 `Dog` 類別繼承 `Animal` 類別的屬性和方法,並覆寫 `speak` 方法。
---
### 多重繼承 (Multiple Inheritance)
```python
class Flyer:
def fly(self):
return "Flying high"
class Swimmer:
def swim(self):
return "Swimming fast"
class Duck(Flyer, Swimmer):
pass
# 創建 Duck 類別的實例
duck1 = Duck()
print(duck1.fly()) # 輸出: Flying high
print(duck1.swim()) # 輸出: Swimming fast
```
**說明**:這個範例展示了多重繼承的應用,`Duck` 類別同時繼承了 `Flyer` 和 `Swimmer` 類別。
---
### 封裝 (Encapsulation)
```python
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # 私有屬性
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
return amount
else:
return "Insufficient funds"
def get_balance(self):
return self.__balance
# 創建 BankAccount 類別的實例
account1 = BankAccount("Alice", 100)
account1.deposit(50)
print(account1.get_balance()) # 輸出: 150
```
**說明**:範例展示了如何使用雙底線將 `balance` 屬性設為私有,並提供方法來存取和修改它。
---
### Hash 函數
```python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __hash__(self):
return hash((self.name, self.age))
# 創建 Person 類別的實例並使用 hash
person1 = Person("John", 30)
print(hash(person1)) # 輸出: 會根據 name 和 age 的 hash 值輸出一個整數
```
**說明**:此範例展示了如何在自訂類別中實現 `__hash__` 方法,使其可以被用作字典的鍵或存放在集合中。
---
# **Python 課程第九章:進階函數 - 讀書筆記**
---
#### **1. 一級對象(First Class Objects)**
**定義與特性**
- 在 Python 中,函數被視為一級對象,這意味著它們可以賦值給變數、作為參數傳遞以及作為其他函數的返回值。
- **補充資料**:這種特性使得 Python 的函數可以在程式中靈活使用,類似於變數或對象。
- **程式範例**:
```python
def greet(name):
return f"Hello, {name}!"
# 函數賦值給變數
say_hello = greet
print(say_hello("Alice")) # Output: Hello, Alice!
# 函數作為參數傳遞
def execute_function(func, value):
return func(value)
print(execute_function(greet, "Bob")) # Output: Hello, Bob!
```
**與其他語言的比較**
- Python 和 JavaScript 將函數視為一等公民,賦予它們與字串或數字相同的特權。
- 在 Java 和 C++ 中,函數被視為二級對象,缺乏上述能力。
---
#### **2. 裝飾器(Decorators)**
**高階函數的應用**
- 高階函數是指接受其他函數作為輸入的函數。
- **補充資料**:裝飾器可以用來在不改變原始函數的情況下,新增功能如日誌記錄、訪問控制等。
**Python 中的語法糖**
- Python 提供了裝飾器的語法糖 `@decorator`,簡化了函數包裝的過程。
- **程式範例**:
```python
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something is happening before the function is called.
# Hello!
# Something is happening after the function is called.
```
**Flask 框架中的應用**
- 在 Flask 等框架中,裝飾器被廣泛應用來簡化網頁伺服器的設置,省略傳統協議設置的步驟。
---
#### **3. 生成器(Generator)**
**`yield` 的定義與使用**
- 生成器使用 `yield` 語句來懶加載地生成一系列值,這對於處理大量數據十分高效。
- **補充資料**:生成器不會一次性將所有數據載入記憶體,這使得它們在處理大型數據集時非常有用。
- **程式範例**:
```python
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
counter = count_up_to(5)
for num in counter:
print(num)
# Output: 1 2 3 4 5
```
**`yield from` 的功能**
- `yield from` 語句允許一個生成器將其部分操作委派給另一個生成器。
- **程式範例**:
```python
def generator1():
yield from range(3)
def generator2():
yield from generator1()
yield from range(3, 6)
for value in generator2():
print(value)
# Output: 0 1 2 3 4 5
```
---
#### **4. 迭代(Iteration),可迭代物件與迭代器**
**迭代概念**
- 迭代指的是逐一訪問集合中每個項目的過程,通常透過迴圈完成。
**可迭代物件與迭代器的區別**
- **補充資料**:可迭代物件如列表、字串等,能夠產生迭代器對象,迭代器則負責逐一訪問其中的元素。
- **程式範例**:
```python
my_list = [1, 2, 3]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
```
**Python 中的內部機制**
- Python 的 `for` 迴圈自動處理迭代器,內部調用其 `__next__` 方法。
---
#### **5. 標準輸入、輸出與管道(Stdin, Stdout, and Pipe)**
**標準輸入與輸出的操作**
- 標準輸入(`stdin`)和輸出(`stdout`)是 Python 終端操作的核心。
**重定向與管道功能**
- 重定向運算符 `>`, `>>` 和 `<` 用於覆寫、附加和讀取檔案。
- **補充資料**:這些功能允許將程式的輸出重定向至文件,或從文件中讀取輸入。
- **程式範例**:
```bash
# 將輸出寫入文件
python script.py > output.txt
# 從文件讀取輸入
python script.py < input.txt
```
**管道的概念**
- 管道允許一個程式的輸出用作另一個程式的輸入,這一概念源自 UNIX 系統,便於模組化程式設計。
- **程式範例**:
```bash
# 使用管道將 ls 的輸出傳遞給 grep
ls | grep "pattern"
```
---
第九章中進階函數概念的全面概述,強調 Python 在處理函數、裝飾器、生成器、迭代以及終端 I/O 操作的靈活性和效率,並補充了相關程式範例以便於理解。
---
# **Python 課程第十章:Useful Modules I - 讀書筆記**
### **Useful Modules I 與 Useful Modules II 筆記**
---
### 課程目錄讀書筆記
以下是《Useful Modules I》的內容重點:
---
### **實用模組 I:摘要與說明**
#### **1. OS 模組**
- **功能**:提供操作系統相關功能,支援跨平台的檔案與目錄操作。
- **常見函數**:
- `os.getcwd()`:獲取目前的工作目錄。
- `os.listdir(path='.')`:列出指定目錄中的所有項目。
- `os.rename(oldpath, newpath)`:重命名檔案或目錄。
- `os.remove(filepath)`:永久刪除檔案(無法還原)。
- `os.rmdir(directorypath)`:刪除空目錄。
- `os.mkdir(name)`:建立新目錄。
- **os.path 子模組**:
- `os.path.join(path1, path2)`:智能拼接路徑,提升代碼可讀性與可移植性。
- `os.path.split(path)`:分割檔案名稱與目錄名稱。
- `os.path.exists(path)`:檢查檔案或目錄是否存在。
- **應用場景**:適用於需要操作系統層面檔案與目錄管理的場景。
#### **2. Collections 模組**
- **功能**:提供 Python 的內建容器(如 `list`、`dict`)的替代數據結構。
- **三種主要數據結構**:
- **`Counter`**:計算元素出現頻率的字典子類別。
- **`defaultdict`**:允許設定預設值的字典,避免 `KeyError`。
- **`namedtuple`**:帶有名稱的元組,結合元組的簡潔性與字典的可讀性。
- **應用場景**:數據計數、處理預設值結構,以及需要更清晰的代碼結構時。
#### **3. Datetime 模組**
- **功能**:處理日期與時間的工具。
- **Datetime 類別**:
- `datetime.now()`:獲取當前時間。
- `datetime.strptime(format)`:根據指定格式解析字串為日期。
- **Timedelta 類別**:
- 表示時間間隔,可用於計算日期與時間差異。
- 支援與 `datetime` 的運算。
- **應用場景**:需要處理時間計算或格式化的場景。
#### **4. Math 模組**
- **功能**:提供數學常數與函數支持。
- **常數**:
- `math.pi`:圓周率。
- `math.e`:自然對數底數。
- **常見函數**:
- `math.sqrt(x)`:計算平方根。
- `math.log(x, base)`:計算對數(可指定底數)。
- `math.ceil(x)`:取上界整數。
- `math.floor(x)`:取下界整數。
- **應用場景**:數值計算與分析。
#### **5. Random 模組**
- **功能**:生成偽隨機數的工具。
- **常見函數**:
- `random.randint(a, b)`:生成指定範圍內的隨機整數。
- `random.choice(seq)`:從序列中隨機選擇一個元素。
- `random.shuffle(seq)`:隨機打亂序列順序。
- **安全隨機數**:使用 `SystemRandom` 提供更高安全性的隨機數生成。
- **應用場景**:遊戲開發、數據抽樣、機器學習模型測試。
---
#### 1. **OS Module**
- **文件系統概念與不同操作系統差異**
- Python的`os`模組提供了跨平台的文件與目錄操作功能。
- 常用於管理文件系統的操作,例如讀取、寫入、重命名與刪除文件。
- **常用函數 (`os.getcwd`, `os.listdir`, 等)**
- `os.getcwd()`:獲取當前工作目錄。
- `os.listdir(path)`:列出指定目錄中的所有文件和目錄。
- **`os.path` 子模組函數**
- `os.path.join(path, *paths)`:合併路徑,增加代碼可讀性與可移植性。
- `os.path.split(path)`:將路徑分割為目錄和文件名。
- **文件操作與刪除模組 (`send2trash`, `shutil`)**
- `send2trash`:將文件移至資源回收桶而不是永久刪除。
- `shutil.rmtree(path)`:遞迴地刪除非空目錄。
- **遍歷目錄樹 (`os.walk`)**
- `os.walk(top, topdown=True)`:生成目錄樹的文件名,根據深度優先或廣度優先的方式來遍歷目錄。
**範例:**
```python
import os
import send2trash
# 列出當前目錄和文件
print("當前目錄的內容:", os.listdir(os.getcwd()))
# 將文件移至資源回收桶
send2trash.send2trash('example.txt')
# 遍歷目錄樹
for folderName, subfolders, filenames in os.walk('/path/to/directory'):
print('目前目錄為:' + folderName)
print('子目錄包括:' + str(subfolders))
print('文件包括:' + str(filenames))
print()
```
#### 2. **Collections Module**
- **`Counter`**
- 用於計算元素出現頻率的字典子類型。
- **`defaultdict`**
- 支援預設值的字典,避免`KeyError`。
- **`namedtuple`**
- 提供類似物件的命名元組,結合元組與字典的特性,增強代碼可讀性。
**範例:**
```python
from collections import namedtuple
# 定義一個命名元組
Point = namedtuple('Point', ['x', 'y'])
p1 = Point(1.0, 5.0)
print(p1.x, p1.y)
```
#### 3. **Datetime Module**
- **`datetime` 類別**
- 提供處理日期與時間的功能,如`datetime.now()`獲取當前時間。
- **`timedelta` 類別**
- 表示時間間隔,用於計算日期時間差異。
**範例:**
```python
from datetime import datetime, timedelta
# 獲取當前時間
now = datetime.now()
print("現在時間:", now)
# 計算時間差
future = now + timedelta(days=5)
print("五天後的時間:", future)
```
#### 4. **Math Module**
- 提供常用數學函數與常數,例如`math.pi`、`math.sqrt`。
#### 5. **Random Module**
- 實現隨機數生成,提供隨機選擇與洗牌功能。
- 使用`SystemRandom`確保加密安全性。
**範例:**
```python
import random
# 生成隨機數
print("隨機數:", random.random())
# 隨機選擇
choices = ['apple', 'banana', 'cherry']
print("隨機選擇:", random.choice(choices))
```
### 總結
本章節介紹了多個Python標準模組,包括操作系統模組、集合模組、日期時間模組、數學模組和隨機數模組。這些模組提供了強大的功能,能夠大幅提高代碼的可讀性和可維護性,並能在日常的程序開發中提供便利。學習和掌握這些模組的應用,可以更加高效地解決各種問題。
---
## **Useful Modules I**
### **1. OS 模組**
#### 功能
提供操作系統相關功能,支援跨平台的檔案與目錄操作。
#### 常見函數與範例
- **`os.getcwd()`**:獲取目前的工作目錄。
```python
import os
print(os.getcwd()) # 輸出:當前工作目錄
```
- **`os.listdir(path='.')`**:列出指定目錄中的所有項目。
```python
print(os.listdir('.')) # 輸出:目錄下所有文件和子目錄
```
- **`os.rename(oldpath, newpath)`**:重命名檔案或目錄。
```python
os.rename('old_file.txt', 'new_file.txt')
```
- **`os.mkdir(name)`**:建立新目錄。
```python
os.mkdir('new_folder')
```
#### `os.path` 子模組
- **`os.path.join(path1, path2)`**:拼接路徑。
```python
path = os.path.join('folder', 'file.txt')
print(path) # 輸出:folder/file.txt
```
- **`os.path.exists(path)`**:檢查檔案或目錄是否存在。
```python
print(os.path.exists('file.txt')) # 輸出:True 或 False
```
---
### **2. Collections 模組**
#### 功能
提供 Python 的內建容器(如 `list`、`dict`)的替代數據結構。
#### 常用數據結構與範例
- **`Counter`**:計算元素出現頻率的字典子類別。
```python
from collections import Counter
data = ['a', 'b', 'a', 'c', 'b', 'a']
count = Counter(data)
print(count) # 輸出:Counter({'a': 3, 'b': 2, 'c': 1})
```
- **`defaultdict`**:允許設定預設值的字典。
```python
from collections import defaultdict
dd = defaultdict(int)
dd['key1'] += 1
print(dd) # 輸出:defaultdict(<class 'int'>, {'key1': 1})
```
- **`namedtuple`**:帶有名稱的元組。
```python
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 輸出:10 20
```
---
### **3. Datetime 模組**
#### 功能
處理日期與時間的工具。
#### 常用方法與範例
- **`datetime.now()`**:獲取當前時間。
```python
from datetime import datetime
now = datetime.now()
print(now) # 輸出:當前日期與時間
```
- **`timedelta` 計算時間差**:
```python
from datetime import timedelta
delta = timedelta(days=10)
print(delta) # 輸出:10 days, 0:00:00
```
---
### **4. Math 模組**
#### 功能
提供數學常數與函數支持。
#### 常見函數與範例
- **`math.sqrt(x)`**:計算平方根。
```python
import math
print(math.sqrt(16)) # 輸出:4.0
```
- **`math.log(x, base)`**:計算對數。
```python
print(math.log(100, 10)) # 輸出:2.0
```
---
### **5. Random 模組**
#### 功能
生成偽隨機數的工具。
#### 常見函數與範例
- **`random.randint(a, b)`**:生成指定範圍內的隨機整數。
```python
import random
print(random.randint(1, 10)) # 輸出:1 到 10 之間的整數
```
- **`random.choice(seq)`**:從序列中隨機選擇一個元素。
```python
choices = ['apple', 'banana', 'cherry']
print(random.choice(choices))
```
---
## **Useful Modules II**
以下是《Useful Modules II》的內容重點:
---
### **實用模組 II:摘要與說明**
#### **1. 正則表達式 (Regular Expression)**
- **定義**:用於匹配字串模式的工具,由 Stephen Cole Kleene 在 1950 年代提出,常用於處理非結構化數據。
- **核心語法**:
- `.`:匹配任意單個字符(不包括換行)。
- `[]`:匹配括號內任意字符或範圍(例如 `[a-z]`)。
- `\d`:匹配任意數字;`\D`:匹配非數字字符。
- `*`:匹配 0 次或多次;`+`:匹配 1 次或多次。
- `{m,n}`:匹配 m 到 n 次。
- `\b`:匹配單詞的邊界。
- `|`:匹配多個條件之一(例如 `A|B`)。
- **應用場景**:
- 電子郵件驗證:`r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b'`
- 處理非結構化文本,如檢查格式或提取特定模式。
- **優勢**:處理靈活,適合數據清理與格式驗證。
#### **2. 壓縮檔案與目錄 (Zip Files and Folders)**
- **定義**:使用 Python 的 `zipfile` 模組進行無損數據壓縮和解壓縮。
- **方法**:
- **壓縮單個文件**:使用 `zipfile.ZipFile` 方法。
- **壓縮整個目錄**:
- 方法 1:搭配 `os.walk()` 遍歷子目錄壓縮(不推薦)。
- 方法 2:使用 `shutil.make_archive()`(推薦)。
- **應用場景**:數據打包與傳輸。
#### **3. 計算理論 (Computational Theory)**
- **概念**:
- **正則表達式與有限自動機 (Finite Automata)**:
- Kleene 定理:正則表達式與有限自動機可以互相轉換。
- 有限自動機具有有限狀態,並根據輸入進行狀態轉換。
- **圖靈機 (Turing Machine)**:
- 相比有限自動機更具表達能力,可用於模擬任意算法。
- 示例:圖靈機可處理非正則語言(如 `a^n b^n`)。
- **應用場景**:數學模型研究與算法模擬。
#### **4. Bonus: 正則表達式**
- **遞歸定義**:
- 任意字符集合 Σ 的元素可構成基本正則表達式。
- 複合運算符:`r1 + r2`(選擇)、`r1 r2`(連接)、`r1*`(重複)。
- **範例**:
- Σ = {a, b},定義語言 L:包含至少一個 `a` 的所有字串。
#### **5. Bonus: 有限自動機**
- **規則**:
- 唯一初始狀態,可有多個接受狀態。
- 每個狀態需有針對 Σ 中字符的轉移。
- **範例**:
- 正則表達式 `(a + b)*` 轉換為有限自動機的圖示。
- **應用場景**:語法解析與狀態機設計。
#### **6. Bonus: 圖靈機**
- **概念**:
- 在磁帶上進行讀寫操作,具有左移與右移功能。
- 可處理有限自動機無法接受的語言。
- **範例**:
- 使用圖靈機進行加法運算:輸入 `a^n b^m`,輸出 `a^(n+m)`。
- **應用場景**:計算模型與算法驗證。
---
### **1. 正則表達式 (Regular Expression)**
#### 功能
用於匹配字串模式的工具,由 Stephen Cole Kleene 在 1950 年代提出,常用於處理非結構化數據。
#### 常用語法與範例
- **匹配數字**:
```python
import re
pattern = r'\d+'
result = re.findall(pattern, 'abc123def456')
print(result) # 輸出:['123', '456']
```
- **匹配單詞邊界**:
```python
pattern = r'\bhello\b'
text = 'hello world'
print(re.findall(pattern, text)) # 輸出:['hello']
```
- **驗證電子郵件**:
```python
email_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b'
print(re.match(email_regex, 'user@example.com')) # 輸出:<Match object>
```
---
### **2. 壓縮檔案與目錄 (Zip Files and Folders)**
#### 功能
使用 Python 的 `zipfile` 模組進行無損數據壓縮和解壓縮。
#### 常用方法與範例
- **壓縮單個文件**:
```python
import zipfile
with zipfile.ZipFile('example.zip', 'w') as zf:
zf.write('file.txt')
```
- **壓縮整個目錄**:
```python
import shutil
shutil.make_archive('example_dir', 'zip', 'path_to_directory')
```
- **解壓縮檔案**:
```python
with zipfile.ZipFile('example.zip', 'r') as zf:
zf.extractall('output_folder')
```
---
### **3. 計算理論 (Computational Theory)**
#### 正則表達式與有限自動機
- **範例**:正則表達式轉換為有限自動機。
```python
# 例:正則表達式 (a|b)* 的有限自動機
# 狀態轉移示例(僅圖示描述)
# 初始狀態 --a--> 狀態1 --b--> 接受狀態
```
#### 圖靈機 (Turing Machine)
- **範例**:模擬圖靈機加法操作。
```python
def turing_addition(input_str):
tape = list(input_str)
head = 0
while head < len(tape):
if tape[head] == 'a':
tape[head] = 'A'
elif tape[head] == 'b':
tape[head] = 'a'
head += 1
return ''.join(tape)
print(turing_addition('aaa#bbb')) # 輸出:'aaaaaa'
```
---
### **4. Bonus: 正則表達式**
#### 遞歸定義與範例
- **範例**:
```python
pattern = r'(a|b)*'
text = 'ababab'
print(re.fullmatch(pattern, text)) # 輸出:<Match object>
```
---
### **5. Bonus: 有限自動機**
#### 規則與範例
- **範例**:正則表達式 `(a + b)*` 的有限自動機圖示。
```python
# 狀態遷移圖:
# 初始狀態 --> 狀態A (接受) --> 狀態B (接受)
```
---
### **6. Bonus: 圖靈機**
#### 概念與範例
- **範例**:處理非正則語言的圖靈機。
```python
def turing_language_processor(input_str):
tape = list(input_str)
head = 0
while head < len(tape):
if tape[head] == 'a':
tape[head] = 'A'
head += 1
return ''.join(tape)
print(turing_language_processor('aaabbb')) # 輸出:'AAAbbb'
```
---
## <font size="6" color="red">[補充]</font> —查找函式(function)及方法(method)使用語法的幾種常見方式:
### 1. **使用內建的 `help()` 函式**
- `help()` 是 Python 的內建函式,用於查看函式或方法的使用說明。
- 範例:
```python
help(print) # 查看 print 函式的使用說明
help(str.lower) # 查看字串方法 lower 的使用說明
```
---
### 2. **使用 `dir()` 查看可用方法或屬性**
- `dir()` 可用於列出物件所有可用的方法和屬性。
- 範例:
```python
dir(str) # 查看字串物件可用的方法
dir(list) # 查看列表物件可用的方法
```
- 搭配 `help()` 可以深入查看具體方法的說明。
---
### 3. **查詢官方文件**
- Python 官方文件提供詳細的函式與方法說明:
- 官方網站:https://docs.python.org/zh-tw/3/
- 例如:
- 標準庫函式:https://docs.python.org/zh-tw/3/library/functions.html
- 字串方法:https://docs.python.org/zh-tw/3/library/stdtypes.html#string-methods
---
### 4. **使用 IDE 或編輯器的內建工具**
- 大多數 IDE 或編輯器(例如 VS Code、PyCharm、Jupyter Notebook)都有以下功能:
- **自動補全**:輸入物件名稱後,按 `.` 會顯示所有可用方法。
- **內嵌說明**:將滑鼠移到方法名稱上,通常會顯示該方法的說明。
---
### 5. **使用網路查詢**
- 直接在網路搜尋函式或方法名稱,例如:「Python `list.append` 說明」。
- 使用 Stack Overflow 等社群網站找到實際案例。
---
### 6. **嘗試 `__doc__` 屬性**
- 許多函式與方法都有內建的說明文件,可以透過 `__doc__` 屬性查看。
- 範例:
```python
print(print.__doc__) # 查看 print 函式的說明
print(str.lower.__doc__) # 查看字串方法 lower 的說明
```
---