# Python - ch.02 資料型別、變數與運算子 [TOC] ## 2-1 Python 資料型別 ### `(2-1-bool1.py)` 布林值 這三行程式碼都是在使用 `bool()` 函式將不同的資料轉換成布林值(`True` 或 `False`)。下面是加上詳細註解的版本: ```python! # 將數值 1 轉為布林值。非零數字會被視為 True print(bool(1)) # 輸出:True # 將數值 0 轉為布林值。0 被視為 False print(bool(0)) # 輸出:False # 將空的 tuple(元組)轉為布林值。空容器(如空字串、空串列、空字典、空集合、空元組)都是 False print(bool(())) # 輸出:False ``` #### ✅ 延伸說明:哪些東西在 `bool()` 中會被視為 False? 下列資料在轉成布林值時會是 `False`: * 數值:`0`, `0.0` * 空字串:`""` * 空串列:`[]` * 空元組:`()` * 空字典:`{}` * 空集合:`set()` * 特殊值:`None` 其他情況幾乎都會是 `True`。 --- ### `(2-1-int1.py)` 整數 這三行程式碼使用了 **Python** 的 `int()` 函式,來將不同型別或不同進位制的值轉換為十進位的整數。以下是**每行加上清楚中文註解的版本**: ```python! # 將整數 100 傳入 int(),保持原樣,結果仍是整數 100 print(int(100)) # 輸出:100 # 將浮點數 3.14 傳入 int(),會「捨去小數部分」轉成整數 print(int(3.14)) # 輸出:3 # 將字串 '100' 視為二進位(base=2)轉為十進位整數 # '100' 在二進位中表示 1×2² + 0×2¹ + 0×2⁰ = 4 print(int('100', 2)) # 輸出:4 ``` #### 🔍 補充說明: | 表達式 | 說明 | 結果 | | :--------------- | :---------------------------: | :---: | | `int(100)` | 已是整數,直接輸出 | 100 | | `int(3.14)` | 浮點數轉整數,**小數捨去** | 3 | | `int('100', 2)` | 把 `'100'` 當成 **二進位** 的數字來轉換 | 4 | --- ### `(2-1-float1.py)` 浮點數 這三行程式碼是使用 `float()` 函式將不同的資料轉換成浮點數(帶小數點的數字)。以下是加上中文註解的版本: ```python! # 將整數 1 轉換成浮點數,結果為 1.0 print(float(1)) # 輸出:1.0 # 將浮點數 3.14 傳入 float(),本身已是浮點數,輸出不變 print(float(3.14)) # 輸出:3.14 # 將字串 '3.1415' 轉換成浮點數 print(float('3.1415')) # 輸出:3.1415 ``` #### 補充說明: - `float()` 可以將整數或字串(格式正確的數字字串)轉為浮點數。 - 字串必須是有效的數字格式,否則會發生錯誤(例如 `float('abc')` 會報錯)。 --- ### `(2-1-str1.py)` 字串 這段程式碼示範了 **Python** 字串不可變(immutable)的特性,這是很重要的觀念。以下是加上註解並說明錯誤原因: ```python! # 建立字串 'Python' 並存入變數 s s = str('Python') # 嘗試將字串第一個字元改成 'Q' # 這會導致錯誤,因為 Python 的字串是不可變的(immutable) # 不能直接改變字串內部的單一字元 s[0] = 'Q' #字串不可更改,會出現錯誤 ``` 輸出結果: --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[6], line 7 2 s = str('Python') 4 # 嘗試將字串第一個字元改成 'Q' 5 # 這會導致錯誤,因為 Python 的字串是不可變的(immutable) 6 # 不能直接改變字串內部的單一字元 ----> 7 s[0] = 'Q' TypeError: 'str' object does not support item assignment #### 為什麼會錯? * **Python** 的字串是不可變物件,無法透過索引直接修改某個字元。 * 你可以用建立新字串的方式來達成想要的結果。 #### 改寫範例:用新字串取代原本字串 ```python! # 利用字串切片和串接,改變第一個字元為 'Q' s = 'Python' s = 'Q' + s[1:] print(s) # 輸出:Qython ``` 這樣就能達到「修改字串中某個字元」的效果,實際上是建立一個新字串並指派回變數。 --- ### `(2-1-type.py)` 使用type顯示資料型別 這段程式碼用來示範不同資料型態的變數宣告及其型別輸出,下面是加上註解的版本: ```python! # 布林值 True,代表真 b = True # 印出 b 的值及其資料型態 <class 'bool'> print(b, type(b)) # 整數 20 num = 20 # 印出 num 的值及其資料型態 <class 'int'> print(num, type(num)) # 浮點數 3.14 pi = 3.14 # 印出 pi 的值及其資料型態 <class 'float'> print(pi, type(pi)) # 字串 "Hello" s = "Hello" # 印出 s 的值及其資料型態 <class 'str'> print(s, type(s)) ``` #### 執行結果範例: True <class 'bool'> 20 <class 'int'> 3.14 <class 'float'> Hello <class 'str'> #### 補充說明: - `type()` 函式會回傳變數的資料型態。 - **Python** 是動態型別語言,變數不用事先宣告型別,會根據賦值自動推斷。 - 常見基本資料型態有:`bool`、`int`、`float`、`str` 等。 --- ## 2-2 變數 ### `(2-2-1a-var1.py)` 印出變數 `a` 之前,變數 `a` 並未參考到任何物件,出現 `NameError` 表示變數 `a` 未定義 這行程式碼會出現錯誤,因為變數 `a` 尚未被定義。 ```python! print(a) ``` #### 🧯 錯誤訊息(範例): --------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[8], line 1 ----> 1 print(a) NameError: name 'a' is not defined #### 🔍 錯誤說明: - **Python** 執行到 `print(a)` 時,會嘗試尋找名為 `a` 的變數。 - 如果之前沒有寫過 `a = ...,Python` 就會報出 `NameError`(名稱錯誤)。 #### ✅ 正確範例: 先定義 `a` 才能使用: ```python! a = 10 print(a) # 輸出:10 ``` --- ### `(2-2-1b-var2.py)` 變數 a 經由「=」參考到不同的物件 ```python! # 將整數 1 指派給變數 a a = 1 # 印出變數 a 的值與它的記憶體位址(透過 id() 函數取得) print(a, id(a)) # 將字串 'Python' 指派給變數 a(此時 a 原本的值 1 被覆蓋) a = 'Python' # 再次印出 a 的值與它的記憶體位址,這時的 id 值會與之前不同 print(a, id(a)) ``` #### ✅ 執行說明(範例輸出會依環境不同而異): 假設輸出如下: 1 140706127547120 Python 2411030893680 可以看到: - 第一次 `a = 1`,`id(a)` 是某個位址(假設是記憶體中的整數物件 `1`)。 - 第二次 `a = 'Python'`,變數 `a` 被重新綁定到一個新的字串物件,記憶體位址也跟著變了。 #### 🔍 核心觀念: - **Python** 中變數是「名稱」或「參考」,不是像 **C/C++** 那樣是「盒子」。 - 當你寫 `a = 1` 時,`a` 被綁定到整數物件 `1`。 - 當你寫 `a = 'Python'` 時,`a` 被綁定到字串物件 `'Python'`,與原本的 `1` 無關。 --- ### `(2-2-1c-var3.py)` 變數 `y` 經由「=」參考到變數 `x` 所參考的物件,變數 `x` 與變數 `y` 參考到相同物件 這段程式碼展示了 **變數指派與記憶體位置(物件 ID)** 的概念,尤其在 **Python** 中變數是「參考」(reference)的語言。以下是加上中文註解與說明的版本: ```python! # 將整數 1 指派給變數 x x = 1 # 將變數 x 的值(也就是整數 1)指派給變數 y # 注意:x 和 y 會指向同一個整數物件(1) y = x # 印出 x 和 y 的記憶體位址(id 值應該相同) print(id(x), id(y)) # 印出 x 和 y 的值 print(x, y) ``` #### ✅ 執行結果(範例): 140706127547120 140706127547120 1 1 你會發現: - `x` 和 `y` 雖然是兩個變數名稱,但它們實際**指向的是同一個物件(數字 1)**。 - 因此 `id(x) == id(y)` 為 **True**。 #### 📌 核心觀念補充: - 在 **Python** 中,整數、浮點數、字串等不可變物件(immutable)會被「重用」。 - 當你寫 `y = x`,你只是讓 `y` 這個變數也指向 `x` 所指的那個物件,並沒有複製新的物件。 #### 🧠 延伸練習: 如果你後續修改 `y` 的值,例如: ```python! y = 2 print(id(x), id(y)) # 這時 id(x) 與 id(y) 就會不同了 ``` 這代表 `y` 改為指向一個新的整數物件 `2`,而 `x` 仍保持為 `1`。 --- ## 2-3 運算子 ### 2-3-1 指定運算子 「指定運算子(Assignment Operators)」是在 **Python** 中用來將某個值指定給變數,並且包含 **結合運算(複合指定)** 的功能,例如 `+=`、`-=` 等。 #### 🧪 範例說明: ```python! x = 10 # x 是 10 x += 5 # 等同 x = x + 5,x 現在是 15 x *= 2 # 等同 x = x * 2,x 現在是 30 x -= 10 # x 現在是 20 x /= 5 # x 現在是 4.0 ``` #### 📌 使用情境: - ✅ 計算累加總和 - ✅ 製作計數器 - ✅ 操作字串或陣列元素時簡化程式 --- ### 2-3-2 算術運算子 算術運算子(Arithmetic Operators)是用來執行基本數學運算的符號,像是加減乘除、次方、取餘數等。以下是 Python 中常見的算術運算子與範例整理: #### 🧮 算術運算子對照表 | 運算子 | 說明 | 範例 | 結果 | | ---- | ------ | --------- | ----- | | `+` | 加法 | `5 + 3` | `8` | | `-` | 減法 | `5 - 2` | `3` | | `*` | 乘法 | `4 * 2` | `8` | | `/` | 除法 | `10 / 4` | `2.5` | | `//` | 整數除法 | `10 // 4` | `2` | | `%` | 餘數 | `10 % 4` | `2` | | `**` | 次方(乘冪) | `2 ** 3` | `8` | #### 🧪 範例程式: ```python! a = 10 b = 3 print("加法 a + b =", a + b) # 13 print("減法 a - b =", a - b) # 7 print("乘法 a * b =", a * b) # 30 print("除法 a / b =", a / b) # 3.333... print("整除 a // b =", a // b) # 3 print("餘數 a % b =", a % b) # 1 print("次方 a ** b =", a ** b) # 1000 ``` #### ✅ 執行結果(範例): 加法 a + b = 13 減法 a - b = 7 乘法 a * b = 30 除法 a / b = 3.3333333333333335 整除 a // b = 3 餘數 a % b = 1 次方 a ** b = 1000 #### 📌 補充說明: - `//`:**整除運算子**,只取商的整數部分。 - `%`:**取餘數**,常用於偶數/奇數判斷或週期性計算。 - `**`:**次方運算子**,例如 `2 ** 3` 表示 2 的 3 次方。 --- ### 2-3-3 比較運算子 **比較運算子(Comparison Operators)** 用來比較兩個值之間的大小或相等關係,比較結果會回傳布林值 `True` 或 `False`。在 Python 中的比較運算子如下: #### 📋 比較運算子對照表: | 運算子 | 說明 | 範例 | 結果 | | ---- | ----- | -------- | ------ | | `==` | 等於 | `5 == 5` | `True` | | `!=` | 不等於 | `5 != 3` | `True` | | `>` | 大於 | `7 > 3` | `True` | | `<` | 小於 | `2 < 4` | `True` | | `>=` | 大於或等於 | `6 >= 6` | `True` | | `<=` | 小於或等於 | `4 <= 5` | `True` | #### 🧪 範例程式: ```python! a = 10 b = 5 print(a == b) # False,a 不等於 b print(a != b) # True,a 不等於 b print(a > b) # True,a 大於 b print(a < b) # False,a 小於 b print(a >= b) # True,a 大於或等於 b print(a <= b) # False,a 小於或等於 b ``` #### ✅ 執行結果(範例): False True True False True False #### ✅ 比較運算子常用情境: - ✅ 判斷數值相等或大小關係 - ✅ if 條件判斷語句(例如 if x > 0:) - ✅ 搭配邏輯運算子(如 and, or)做多重條件判斷 #### 🔄 延伸:字串也能比較! ```python! print("apple" == "apple") # True print("cat" > "apple") # True(字母順序 c > a) ``` --- ### 2-3-4 邏輯運算子 **邏輯運算子(Logical Operators)** 邏輯運算子用來組合多個布林條件,結果依據條件判斷為 `True` 或 `False`,常用於條件判斷和流程控制中。 #### 📋 Python 三大邏輯運算子 | 運算子 | 說明 | 範例 | 解釋 | | ----- | ----- | -------------------------- | ------------------ | | `and` | 並且(且) | `True and False` → `False` | 兩邊都為 True 才是 True | | `or` | 或 | `True or False` → `True` | 只要有一邊為 True 即 True | | `not` | 非(取反) | `not True` → `False` | 將布林值反轉 | #### 🧪 範例程式: ```python! a = 10 b = 5 print(a > 5 and b < 10) # True and True → True print(a > 5 and b > 10) # True and False → False print(a > 5 or b > 10) # True or False → True print(not (a > 5)) # not True → False ``` #### ✅ 執行結果(範例): True False True False #### ✅ 應用情境 - 用於 `if` 條件判斷,例如: ```python! if a > 0 and b > 0: print("a 和 b 都是正數") ``` - 將多個條件組合起來判斷複雜邏輯。 #### 📌 注意事項 - `and`、`or` 是**短路運算**:遇到結果已確定,就不再繼續判斷。 - `not` 只能用在單一布林值或布林表達式。 --- ### 2-3-5 in 與 is 運算子 | 運算子 | 說明 | 舉例 | 結果與補充說明 | |:------:|----------|----------------------------------------------|----------------| | `in` | 是否包含 | `x = 1`<br>`y = [1,2,3]`<br>`x in y` | `True`<br>註:`[1,2,3]` 為串列,下一章會介紹 | | `not in` | 是否不包含 | `x = 1`<br>`y = [1,2,3]`<br>`print(x not in y)` | `False` | | `is` | 是否為相同物件 | `x = [1,2,3]`<br>`y = [1,2,3]`<br>`print(x is y)` | `False` | | `is not` | 是否不為相同物件 | `x = [1,2,3]`<br>`y = [1,2,3]`<br>`print(x is not y)` | `True` | #### `(2-3-5-is.py)` is 運算子 這段程式碼是用來比較兩個 **列表(list)** 變數的記憶體位置與內容相等性。以下是逐行解說與中文註解: ```python! # 建立一個列表 x,內容為 [1, 2, 3] x = [1, 2, 3] # 再建立另一個列表 y,內容也為 [1, 2, 3] y = [1, 2, 3] # 印出 x 與 y 的記憶體位置(id) print(id(x), id(y)) # 使用 is 比較 x 和 y 是否為同一個物件(記憶體位置是否一樣) print(x is y) # 結果為 False # 使用 == 比較 x 和 y 的內容是否相等 print(x == y) # 結果為 True ``` #### 🧠 解釋: | 比較方式 | 說明 | 結果 | | -------- | --------------------------- | ------- | | `x is y` | 比較兩個變數是否指向 **同一個記憶體物件**(身份) | `False` | | `x == y` | 比較兩個物件的 **內容是否相等** | `True` | - `x` 和 `y` 都是新的 list 物件,即使內容相同,記憶體位址(`id()`)也不同。 - 所以 `x is y` 為 `False`,但 `x == y` 為 `True`。 #### ✅ 範例輸出(會依系統記憶體配置而異): 140262717719744 140262717720448 False True #### 📌 延伸說明: 如果你寫的是: ```python! y = x ``` 那麼 `x is y` 就會變成 `True`,因為它們指向同一個 **list**。 --- ## 2-4 字串 ### `(2-4-string1.py)` 使用單引號「'」與雙引號「"」所包夾的文字,在 **Python** 會被視為字串 這段程式碼示範了 Python 字串的基本建立方法:使用單引號 `'...'`、雙引號 `"..."`、以及三重引號 `'''...'''`(或 `"""..."""`)來處理不同情況的文字。以下是逐行說明與中文註解版本: ```python! # 使用單引號建立一行字串 s1 = '春眠不覺曉,處處聞啼鳥。' print(s1) # 輸出:春眠不覺曉,處處聞啼鳥。 ``` ```python! # 使用雙引號建立另一行字串 s2 = "夜來風雨聲,花落知多少。" print(s2) # 輸出:夜來風雨聲,花落知多少。 ``` ```python! # 單引號字串中包含雙引號內容,這樣寫是合法的 s3 = '作者"孟浩然" 詩名"春曉"' print(s3) # 輸出:作者"孟浩然" 詩名"春曉" ``` ```python! # 雙引號字串中包含單引號內容,也完全沒問題 s4 = "作者'孟浩然' 詩名'春曉'" print(s4) # 輸出:作者'孟浩然' 詩名'春曉' ``` ```python! # 使用三重單引號建立多行字串(可以跨行、保留換行與空格) s5 = ''' 春眠不覺曉,處處聞啼鳥。 夜來風雨聲,花落知多少。 作者"孟浩然" 詩名"春曉" ''' print(s5) ``` #### 📌 三重引號 `'''...'''` 或 `"""..."""` 的特點: - 可用來建立「多行字串」。 - 保留原始的 **換行符號與縮排空格**。 - 適合用來寫詩、文章、註解段落、長文字。 #### ✅ 輸出範例(含換行): 春眠不覺曉,處處聞啼鳥。 夜來風雨聲,花落知多少。 作者"孟浩然" 詩名"春曉" --- ### `(2-4-1-string2.py)` 字串運算子 這段程式碼展示了 **Python 字串的串接、重複、索引、切片**與**轉向技巧**,也包含了特殊字元如 `\n`(換行)、`\t`(跳格/tab)的應用。以下是詳細中文註解與對照範例: #### 🔹 字串串接與重複 ```python! s1 = '01234' s2 = '56789' s3 = s1 + s2 # 串接字串 s1 和 s2 print(s3) # 輸出:0123456789 ``` ```python! s1 = '01234' s2 = s1 * 2 # 重複 s1 兩次 print(s2) # 輸出:0123401234 ``` #### 🔹 字串索引與切片 **切片(slice)** 語法 `s[start:end:step]` ```python! s = '0123456789' print('s=', s, 's[0]=', s[0]) # 第一個字元:0 print('s=', s, 's[1]=', s[1]) # 第二個字元:1 print('s=', s, 's[-1]=', s[-1]) # 最後一個字元:9 print('s=', s, 's[-2]=', s[-2]) # 倒數第二個字元:8 print('s=', s, 's[:]=', s[:]) # 全部切出:0123456789 print('s=', s, 's[5:]=', s[5:]) # 從第 5 個位置開始到結尾:56789 print('s=', s, 's[-2:]=', s[-2:]) # 從倒數第 2 位到結尾:89 print('s=', s, 's[:5]=', s[:5]) # 從開頭到第 4 位(不含第5):01234 print('s=', s, 's[:-2]=', s[:-2]) # 從開頭到倒數第 3 位(不含倒數2):01234567 print('s=', s, 's[7:9]=', s[7:9]) # 第 7 到第 8 位(不含9):78 print('s=', s, 's[-4:-1]=', s[-4:-1]) # 倒數第 4 到倒數第 2 位(不含-1):678 print('s=', s, 's[5:-2]=', s[5:-2]) # 第 5 到倒數第 3 位(不含倒數2):567 print('s=', s, 's[2:10:2]=', s[2:10:2]) # 每隔 2 個字元取值(從第 2 到第 9):2468 print('s=', s, 's[::-1]=', s[::-1]) # 整串反轉:9876543210 print('s=', s, 's[-1::-1]=', s[-1::-1]) # 同上,從最後一位倒著取到第一位:9876543210 ``` #### ✅ 執行結果(範例): s= 0123456789 s[0]= 0 s= 0123456789 s[1]= 1 s= 0123456789 s[-1]= 9 s= 0123456789 s[-2]= 8 s= 0123456789 s[:]= 0123456789 s= 0123456789 s[5:]= 56789 s= 0123456789 s[-2:]= 89 s= 0123456789 s[:5]= 01234 s= 0123456789 s[:-2]= 01234567 s= 0123456789 s[7:9]= 78 s= 0123456789 s[-4:-1]= 678 s= 0123456789 s[5:-2]= 567 s= 0123456789 s[2:10:2]= 2468 s= 0123456789 s[::-1]= 9876543210 s= 0123456789 s[-1::-1]= 9876543210 補充: ```python! print(s[-2::]) ``` - `s[-2::]` 是使用 **切片語法** `s[start:end:step]`: - `start = -2` → 從倒數第 2 個字元開始(也就是字元 `'8'`) - `end` 省略 → 代表切到最後 - `step = 1`(預設)→ 正向一個一個取 ✅ 結果輸出: 89 📘 延伸說明: | 表達式 | 結果 | 說明 | | ----------- | ---------- | ---------------- | | `s[-2::]` | `'89'` | 從 `'8'` 開始,一直到最後 | | `s[-2::-1]` | `'87...0'` | 從 `'8'` 開始向前倒著取 | | `s[1:-2:3]` | `'147'` | 從 `'1'` 開始每隔 `3` 個字元取到倒數2 (`'8'`) (不含倒數2 `'8'`) | ```python! print(s[:-5]) ``` 是在使用 **Python** 的 **字串切片(slice)** 語法,格式是 `s[start:end]`。 🔍 解讀 `s[:-5]` - `s = '0123456789'` - `start`:預設為 `0`(從開頭) - `end = -5`:表示切到 **倒數第 5 個字元的「前一個」位置** - `step`:省略,預設為 `1`(正向) 📤 輸出結果: 01234 #### 🔹 多行字串 + 特殊字元 ```python! s = '春眠不覺曉,處處聞啼鳥。\n\ 夜來風雨聲,花落知多少。\n\ \t作者"孟浩然" 詩名"春曉"' print(s) ``` ##### 📌 說明: - `\n`:換行 - `\t`:Tab 鍵(縮排) - 多行用 `\` 續行,也可以改用 `'''...'''` 寫法更直觀 ##### ✅ 輸出結果: ```arduino! 春眠不覺曉,處處聞啼鳥。 夜來風雨聲,花落知多少。 作者"孟浩然" 詩名"春曉" ``` #### 📘 小結:常見字串操作 | 操作 | 範例 | 結果 | | -- | -------------- | ---------- | | 串接 | `'ab' + 'cd'` | `'abcd'` | | 重複 | `'ha' * 3` | `'hahaha'` | | 索引 | `'abc'[1]` | `'b'` | | 切片 | `'abcde'[1:4]` | `'bcd'` | | 反轉 | `'abc'[::-1]` | `'cba'` | --- ### `(2-4-2-string3.py)` 字串的內建函式 這段程式碼展示了 **Python 字串處理的多種常用方法**,包含分割、合併、取代、搜尋、格式對齊、大小寫轉換、補零、去除空白等功能。以下是完整的中文註解與說明: #### **🔹 分割字串 `split()` + 合併字串 `join()`** ```python! s1 = '春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。' list1 = s1.split(',') # 以「,」切割字串,產生清單 print(list1) # 輸出:['春眠不覺曉', '處處聞啼鳥', '夜來風雨聲', '花落知多少。'] s2 = ','.join(list1) # 用「,」把 list1 重新組合成字串 print(s2) # 輸出:春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 ``` ##### ✅ 輸出結果: ['春眠不覺曉', '處處聞啼鳥', '夜來風雨聲', '花落知多少。'] 春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 #### 🔹 字串取代 `replace()` ```python! s3 = s1.replace('春', '冬') # 把字串中第一個 '春' 換成 '冬' print(s3) # 輸出:冬眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 ``` ##### ✅ 輸出結果: 冬眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 #### 🔹 查找字串位置` find()`、`rfind()` ```python! print("s1為", s1, '在s1的', s1.find('花落'), '位置發現"花落"') # find() 從左邊開始找子字串的位置(回傳起始索引) print("s1為", s1, '在s1中從右邊數過來第一個出現"處"的位置為', s1.rfind('處')) # rfind() 從右邊開始找子字串的位置(回傳起始索引) ``` ##### ✅ 輸出結果: s1為 春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 在s1的 18 位置發現"花落" s1為 春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 在s1中從右邊數過來第一個出現"處"的位置為 7 #### 🔹 開頭結尾檢查 `startswith()`、`endswith()` ```python! print(s1.startswith('春眠')) # 檢查 s1 是否以 "春眠" 開頭 → True print(s1.endswith('多少。')) # 檢查 s1 是否以 "多少。" 結尾 → True ``` ##### ✅ 輸出結果: True True #### 🔹 子字串出現次數 `count()` ```python! print('s1=', s1, "s1.count('處')等於", s1.count('處')) # 計算 "處" 出現幾次 → 2 次 ``` ##### ✅ 輸出結果: s1= 春眠不覺曉,處處聞啼鳥,夜來風雨聲,花落知多少。 s1.count('處')等於 2 #### 🔹 對齊格式(寬度10) ```python! s1 = '春眠不覺曉' print(s1.center(10)) # 置中對齊 → 空白填滿左右 print(s1.rjust(10)) # 靠右對齊 print(s1.ljust(10)) # 靠左對齊 ``` ##### ✅ 輸出結果: 春眠不覺曉 春眠不覺曉 春眠不覺曉 #### 🔹 英文字串轉換大小寫 ```python! s1 = 'An apple a day.' print(s1.capitalize()) # 首字大寫 → An apple a day. print(s1.title()) # 每個單字首字大寫 → An Apple A Day. print(s1.swapcase()) # 大小寫互換 → aN APPLE A DAY. print(s1.upper()) # 全部轉大寫 → AN APPLE A DAY. print(s1.lower()) # 全部轉小寫 → an apple a day. ``` ##### ✅ 輸出結果: An apple a day. An Apple A Day. aN APPLE A DAY. AN APPLE A DAY. an apple a day. #### 🔹 數字補零 `zfill()` ```python! s1 = '123' print(s1.zfill(5)) # 左側補零至長度 5 → 00123 ``` ##### ✅ 輸出結果: 00123 #### 🔹 去除空白字元(或自訂字元) ```python! s1 = ' Hello,Mary. ' print(s1.strip()) # 去除左右兩側空白 → Hello,Mary. print(s1.lstrip(' H')) # 去除左側的 ' ' 和 'H' → ello,Mary. print(s1.rstrip(' .')) # 去除右側的空白與句點 → Hello,Mary ``` ##### ✅ 輸出結果: Hello,Mary. ello,Mary. Hello,Mary #### ✅ 小結:常用字串處理函式功能速查 | 函式名 | 功能描述 | | -------------- | ------------- | | `split()` | 分割字串為清單 | | `join()` | 將清單合併為字串 | | `replace()` | 替換字串中的子字串 | | `find()` | 從左找子字串的位置 | | `rfind()` | 從右找子字串的位置 | | `count()` | 統計子字串出現次數 | | `startswith()` | 是否以某字串開頭 | | `endswith()` | 是否以某字串結尾 | | `center()` | 置中對齊字串(寬度) | | `ljust()` | 靠左對齊 | | `rjust()` | 靠右對齊 | | `capitalize()` | 首字母大寫 | | `title()` | 每個單字首字母大寫 | | `upper()` | 全部大寫 | | `lower()` | 全部小寫 | | `swapcase()` | 大小寫互換 | | `zfill()` | 左邊補零(常用於數字格式) | | `strip()` | 去除兩側空白或指定字元 | | `lstrip()` | 去除左側空白或指定字元 | | `rstrip()` | 去除右側空白或指定字元 | --- ## 2-5 範例練習 ### `(2-5-1-服裝訂購系統.py)` 這段程式碼是一個簡單的 **服裝訂購總金額計算器**,讓使用者輸入上衣、褲子、背心的數量,然後計算總價。以下是加上中文註解的版本: ```python! # 輸入上衣數量,轉換為整數型態並存入變數「上衣」 上衣 = int(input('請輸入上衣數量?')) # 輸入褲子數量,轉換為整數型態並存入變數「褲子」 褲子 = int(input('請輸入褲子數量?')) # 輸入背心數量,轉換為整數型態並存入變數「背心」 背心 = int(input('請輸入背心數量?')) # 計算總金額(上衣單價300、褲子350、背心400) 總金額 = 上衣 * 300 + 褲子 * 350 + 背心 * 400 # 輸出結果 print('訂購服裝的總金額為', 總金額) ``` #### ✅ 輸出結果: 請輸入上衣數量?2 請輸入褲子數量?3 請輸入背心數量?1 訂購服裝的總金額為 2050 #### 🧮 範例輸入與輸出: 假設使用者輸入: 請輸入上衣數量?2 請輸入褲子數量?1 請輸入背心數量?3 則輸出為: 訂購服裝的總金額為 2150 #### ✅ 延伸建議(進階版本): 你也可以用 `f-string` 讓輸出更整齊: ```python! print(f"訂購服裝的總金額為 {總金額} 元") ``` --- ### `(2-5-2-計算圓面積與圓周長.py)` 這段程式碼是用來**計算圓的周長與面積**,根據使用者輸入的半徑,使用圓周率公式進行運算。下面是詳細的**中文註解版本**: ```python! # 讓使用者輸入半徑,轉為浮點數型別(小數也可以輸入) 半徑 = float(input('請輸入半徑?')) # 設定圓周率常數(π) PI = 3.14159 # 計算圓周長:公式為 2 × π × 半徑 圓周長 = 2 * PI * 半徑 # 計算圓面積:公式為 π × 半徑² 圓面積 = 半徑 * 半徑 * PI # 輸出結果(不限制小數點位數) print('圓周長為', 圓周長, '圓面積為', 圓面積) ``` #### ✅ 輸出結果: 請輸入半徑?10 圓周長為 62.8318 圓面積為 314.159 #### 🧮 範例輸入與輸出: 如果輸入: 請輸入半徑?5 則輸出結果為: 圓周長為 31.4159 圓面積為 78.53975 #### ✅ 加強版本建議(含小數點格式化): 如果你想讓數字顯示更整齊,例如保留小數點 2 位,可以這樣寫: ```python! print(f'圓周長為 {圓周長:.2f},圓面積為 {圓面積:.2f}') ``` 輸出: 圓周長為 31.42,圓面積為 78.54 ### `(2-5-3-攝氏轉華氏.py)` 這段程式碼是用來**將攝氏溫度轉換為華氏溫度**,是非常常見的單位轉換應用。以下是加上清楚中文註解的版本: ```python! # 讓使用者輸入攝氏溫度,並轉換為浮點數型態 c = float(input('請輸入攝氏溫度?')) # 溫度轉換公式:華氏 = 攝氏 × 9/5 + 32 f = c * 9 / 5 + 32 # 輸出結果 print('華氏溫度為', f) ``` #### 🧮 公式回顧: $$ °F \ = \ °C \ × \ \frac{9}{5} \ + \ 32 $$ #### ✅ 範例輸入與輸出: 假設使用者輸入: 請輸入攝氏溫度?25 輸出: 華氏溫度為 77.0 #### 🔧 建議格式化輸出(小數點顯示更清楚): ```python! print(f'攝氏 {c:.1f} 度 = 華氏 {f:.1f} 度') ``` 輸出結果: 攝氏 25.0 度 = 華氏 77.0 度 ### `(2-5-4-複利計算.py)` 這段程式碼是用來計算 **本金加年利率的複利結果**,也就是**每年利息會計入本金繼續計算**,屬於「複利計算」的範例。以下是加上詳細中文註解的版本: #### ✅ 加註解版本: ```python! # 輸入本金(整數型別) money = int(input('請輸入本金?')) # 輸入年利率(百分比形式),轉換為浮點數 interest = float(input('請輸入年利率(%)?')) # 計算第1年本利和:本金 × (1 + 年利率) y1 = money * (1 + interest / 100) # 計算第2年本利和:本金 × (1 + 年利率)^2 y2 = money * ((1 + interest / 100) ** 2) # 計算第3年本利和:本金 × (1 + 年利率)^3 y3 = money * ((1 + interest / 100) ** 3) # 輸出三年的本利和 print('第一年本利和為', y1) print('第二年本利和為', y2) print('第三年本利和為', y3) ``` ##### 🧮 複利公式小提醒: $$ A \ = \ P \ × \ (1+r)^n $$ - `A`:本利和(總金額) - `P`:本金 - `r`:年利率(百分比需除以 100) - `n`:年數 #### 🧪 範例輸入: 請輸入本金?10000 請輸入年利率(%)?5 #### 🧾 輸出結果: 第一年本利和為 10500.0 第二年本利和為 11025.0 第三年本利和為 11576.25 ### `(2-5-5-迴文.py)` 這段程式碼是用來**判斷輸入的字串是否為「迴文」(Palindrome)**,非常簡潔有效!下面是加上中文註解的版本: ```python! # 輸入一個字串 s = input('請輸入一個字串?') # 反轉字串:s[::-1] 是從右邊開始以-1步長反向切片 # 判斷字串是否與其反轉後相等 print('迴文判斷結果為', s == s[::-1]) ``` #### ✅ 輸出結果: ```sgraphql! 請輸入一個字串? abvba 迴文判斷結果為 True ``` #### 📌 什麼是迴文? 迴文是指「正著讀和反著讀都一樣」的字串,例如: - `"abba"` - `"12321"` - `"上海自來水來自海上"`(中文也成立) #### 🧪 範例輸入與輸出: **輸入:** 請輸入一個字串?12321 **輸出:** 迴文判斷結果為 True #### ✅ 延伸:忽略大小寫與空白 如果你想進階處理「忽略大小寫、空白與標點」,可用以下改進版: ```python! import re # 匯入正則表示式模組(regular expression) # 使用者輸入字串 s = input('請輸入一個字串?') # 用正則表達式過濾掉所有「不是」中英文與數字的字元 # ^ 表示取反,[] 是字元集合,a-zA-Z0-9 是英文和數字,一-龥 是常見中文字範圍 # re.sub() 表示將匹配到的字元「替換成空字串」 s_clean = re.sub(r'[^a-zA-Z0-9一-龥]', '', s).lower() # 判斷處理後的字串是否為迴文(與反轉後結果相同) print('迴文判斷結果為', s_clean == s_clean[::-1]) ``` #### 📘 支援中英文、忽略標點與大小寫,例如 `"A man, a plan, a canal: Panama"` 也能判斷為 True。 #### ✅ 範例測試: ```text! 請輸入一個字串?A man, a plan, a canal: Panama 迴文判斷結果為 True ``` ```text! 請輸入一個字串?上海自來水來自海上 迴文判斷結果為 True ``` #### 📌 重點技巧解析: + `re.sub(r'[^a-zA-Z0-9一-龥]', '', s)`: - 移除所有非中英文與數字 + `.lower()`:將字串轉小寫(忽略大小寫差異) + `s[::-1]`:反轉字串(Python 切片技巧) #### 🧠 正則表達式說明: ```regex! [^a-zA-Z0-9一-龥] ``` + `^`:非 + `a-zA-Z`:英文大小寫 + `0-9`:阿拉伯數字 + `一-龥`:常見的中文字範圍(不含全部罕用字) 這樣可以**保留中英文與數字,排除標點、空格與符號**。 如果你想把它改寫成一個可重複使用的函式,可以這樣寫: ```python! def is_palindrome(s): s_clean = re.sub(r'[^a-zA-Z0-9一-龥]', '', s).lower() return s_clean == s_clean[::-1] ```