【Python基礎教學】型態轉換&運算子&條件控制【part-5】 === 目錄(Table of Contents) [TOC] --- 哈囉大家好,很感謝你點進本文章,我是一名高中生,是電腦社社團的社長,由於我並不是 Python 這方面非常精通的專家,所以若文章有些錯誤請見諒,也可向我指正錯誤。另外本文章的用意是作為電腦社社團的教材使用而編寫的。 接下來,讓我們進入正題。 數據型態的轉換 --- 之前我們有說到關於隱式轉換的部分,那既然會有隱式轉換(implicit conversion),當然也就有顯式轉換(explicit cast)了。 Python 資料型態轉換可以分為兩種: * **隱式轉換(implicit conversion)**:自動完成。 * **顯式轉換(explicit cast)**:需要使用函數來轉換。 ### 隱式轉換(implicit conversion) --- > 在隱式轉換中,Python 會自動將一種資料型態轉換為另一種資料型態,不需要我們自己去干預。 接下來我們來看一個範例,在這範例中,我們將兩種不同型態的資料進行運算,較低資料型態(整數)就會轉換為較高資料型態(浮點數)以避免資料遺失。 至於什麼是較低資料型態、較高資料型態?待會再繼續說明。 ```python= num_int = 123 num_float = 1.23 num_new = num_int + num_float print("num_int 資料型態為:", type(num_int)) print("num_float 資料型態為:", type(num_float)) print("num_new 值為:", num_new) print("num_new 資料型態為:", type(num_new)) ``` ![image](https://hackmd.io/_uploads/BkLC49x66.png) 輸出結果: ![image](https://hackmd.io/_uploads/Sk2lBqg6p.png) 可以看到我們宣告兩個變數,第一個為 num_int,作為整數(integer)int;第二個為 num_float,作為浮點數(float)。之後第四行宣告變數 num_new,為兩個不同資料型態做相加。 我們印出 num_int、num_float 兩變數的資料型態,再印出 num_new,也就是兩者相加之後的資料型態,可以發現 num_new 在相加過後,Python 就自動將它隱式轉換成 float。 好,我們再回過頭來說:何謂較低資料型態、較高資料型態?這是隱式轉換中用於描述資料型態精度的概念。而精度我們可以解釋成「這個資料型態能夠顯示出的訊息多寡」,比如 float 就比 int 還高,它除了能夠顯示整數以外,還能顯示小數。 > 通常情況下,Python的資料型態的「高、低」可以依照以下順序理解:布林(bool) < 整數(int) < 浮點數(float)< 複數(complex)。這個順序主要根據資料型態可以表示的資訊範圍和精確度來決定的。 那麼當我們理解隱式轉換的概念後,我們繼續前進,來學習何謂顯式轉換(explicit cast)。 ### 顯式轉換(explicit cast) --- 顯式轉換其實非常簡單,就只是利用預定義函數來將某個物件的資料型態轉換而已。接下來以下範例我們會使用 int()、float()、str() 等預定義函數來進行顯式轉換。 :::info 內建函數(built-in function):或稱預定義函數,也就是原本早就內建在 Python 當中的函數,不需要額外透過引入就可以呼叫的函數。 ::: int() 強制轉換為整數: ```python= x = int (1) # x 輸出結果為 1 y = int (2.8) # y 輸出結果為 2 z = int ("3") # z 輸出結果為 3 ``` float() 強制轉換為浮點數: ```python= x = float(1)     # x 輸出結果為 1.0 y = float(2.8)   # y 輸出結果為 2.8 z = float("3")   # z 輸出結果為 3.0 w = float("4.2") # w 輸出結果為 4.2 ``` str() 強制轉換成字串: ```python= x = str("s1") # x 輸出結果為 's1' y = str(2) # y 輸出結果為 '2' z = str(3.0) # z 輸出結果為 '3.0' ``` 好,那基本上就是這樣,有關於顯式轉換的部分,以下有個表格,列出所有 Python 中的內建函數,可以用來執行資料型態之間的轉換: | 函數 | 描述 | | -------- | -------- | | int(x [, base]) | 將物件 x 轉換為一個整數,base為要轉換的進制(二進制、八進制等)例:int(x, 10) | | float(x) | 將物件 x 轉換為一個浮點數 | | complex(real [,imag]) | 創建一個複數 | | str(x) | 將物件 x 轉換為字串 | | repr(x) | 將物件x 轉換為表達式字串,想知道 str 與 repr 的詳情,可見該網站:[python repr與str雜談](https://ithelp.ithome.com.tw/articles/10194593) | | eval(str) | 用來計算在字串中的有效 Python 表達式,並回傳一個物件。例:eval("3 * 8") 等於 24。 | | tuple(s) | 將序列 s 轉換為一個元組 | | list(s) | 將序列 s 轉換為列表 | | set(s) | 轉換為可變集合 | | dict(d) | 創建一個字典。d 必須是一個(key, value)元組序列。 | | frozenset(s) | 轉換為不可變集合 | | chr(x) | 將一個整數轉換為一個字元 | | ord(x) | 將一個字元轉換為它的整數值(ASCII碼) | | hex(x) | 將一個整數轉換為一個十六進位字串 | | oct(x) | 將一個整數轉換為八進位字串 | | bin(x) | 將一個整數轉換為二進位字串 | 表格來源:[Python3 資料類型轉換| 菜鳥教程](https://www.runoob.com/python3/python3-type-conversion.html) 運算子(operator) --- 什麼是運算子?就是可以拿來做加減乘除等運算的操作的「符號」,例如「 + - * / 」。 舉個簡單的範例: `1 + 1 = 2` 上述範例中,1 稱為運算元,+ 號稱為運算子。 2024/04/26 補運算式解釋: 運算式(expression),由於 expression 具有表達的意思,於是運算式也可以稱為表達式,運算式即「運算子+運算元」,例如:「1 + 1」。 像是「a == b」也是一種運算式哦! 在 Python 中,支援以下多種運算子: * 算術運算子(我個人偏好叫做數學運算子) * 比較(關係)運算子 * 指定(賦值)運算子 * 邏輯運算子 * 位元運算子 * 成員運算子 * 身分運算子 :::success 運算子:進行運算的符號。 運算元:被運算的值。 運算式:運算元+運算子的結構,如:「1 + 1」、「a + b」 ::: 今天我們不談位元運算子,其餘部分都會談到,所以讓我們開始吧。 ### 算術運算子(Arithmetic operator) --- :::success 這樣理解就懂了: 算術運算子 = 加減乘除的符號 ::: 以下表格中,我們假設變數 a=10, b=21: | 運算子 | 描述 | 範例 | | ------ | -------------- | ------------------ | | + | 加法 | a + b 輸出結果 31 | | - | 減法 | a - b 輸出結果 -11 | | * | 乘法 | a * b 輸出結果 210 | | / | 除法 | b / a 輸出結果 2.1 | | % | 取模,取餘數 | b % a 輸出結果 1 | | ** | 乘幂,次方 | a**b 為10的21次方 | | // | 取整除,往小的方向取整數 | ![image](https://hackmd.io/_uploads/B1ey8KWTT.png) | 以下是一個範例: ```python= a = 5 b = 10 print("a + b = ", a+b) print("a - b = ", a-b) print("a * b = ", a*b) print("a / b = ", a/b) print("a % b = ", a%b) print("a ** b = ", a**b) print("a // b = ", a//b) ``` (2024/04/26 補)註:在程式語言的世界中也有先乘除後加減的規則,括號內的算式先算等等。 ### 比較運算子(Comparison operator or Relational operator) --- :::success 這樣理解就懂了: 比較運算子 = 顧名思義,就是可以拿兩數進行比較運算。 ::: 以下表格中,我們假設變數 a=10, b=20: | 運算子 | 描述 | 範例 | | ------ | -------------------------- | --------------------- | | == | 等於,比較兩者之間是否相等 | (a == b) 回傳 False | | != | 不等於,比較兩者之間是否不相等 | (a != b) 回傳 True | | > | 大於,比較兩者之間是否大於另一方。 | (a > b) 回傳 False | | < | 小於,比較兩者之間是否小於另一方。 | (a < b) 回傳 True | | >= | 大於等於,比較兩者之間是否大於或等於另一方。 | (a >= b) 回傳 False | | <= | 小於等於,比較兩者之間是否小於或等於另一方。 | (a <= b) 回傳 True | 以下是在 IDLE shell 介面操作的範例(2024/04/26 補): ```python= >>> a = 10 >>> b = 20 >>> print(a == b) False >>> print(a != b) True >>> print(a > b) False >>> print(a < b) True >>> print(a >= b) False >>> print(a <= b) True ``` ### 指定運算子(Assignment operator) --- :::success 這樣理解就懂了: 指定運算子 = 將繁瑣的指定步驟簡化! 如: 原本是 c = c + b 寫成 c += b 就等同於上面的式子,達成簡化目的。 ::: 以下表格中,我們假設變數 a=10, b=20: | 運算子 | 範例 | | ------ | ---- | | = | c = a + b,意思是將 a + b 相加過後的值指定(賦予)給變數 c。 | | += | c += a 就等於 c = c + a | | -= | c -= a 就等於 c = c - a | | *= | c *= a 就等於 c = c * a | | /= | c /= a 就等於 c = c / a | | %= | c %= a 就等於 c = c % a | | **= | c **= a 就等於 c = c ** a | | //= | c //= a 就等於 c = c // a | 除了上述的運算子之外,我將剩下最後一個運算子單獨拉出來說明,因為他十分特別,能夠在工序上簡化一些不必要的程序,讓程式碼看起來更加簡潔。 `:=` 海象運算子(Walrus operator),此運算符的主要目的是在表達式中同時進行指定和回傳指定的值。**Python3.8 版本新增了此運算子。** > 使用海象運算子可以在某些情況下簡化程式碼,尤其是在需要在表達式中使用指定結果的情況下。這對於簡化循環條件或表達式中的重複計算很有用。 以下是一個範例: ![image](https://hackmd.io/_uploads/Bkeatt-aa.png) 可以看到,可以省略一行宣告變數的工序,而也允許我們在條件語句中同時計算並且指定其變數之值,然後將結果用於比較,能夠減少代碼行數,讓整體看起來更加簡潔。 ### 邏輯運算子(Logical operator) --- :::success 這樣理解就懂了: 邏輯運算子 = 想像成數學上的集合(交集 -> and、聯集 -> or、補集 -> not) ::: ![image](https://hackmd.io/_uploads/SywmwhWap.png) 圖源:[STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/operator.html) ![image](https://hackmd.io/_uploads/ByJHP2Zpp.png) 圖源:[STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/operator.html) ![image](https://hackmd.io/_uploads/Skf_vh-Tp.png) 圖源:[STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/operator.html) 以下表格中,我們假設變數 a=True, b=False: | 運算子 | 邏輯表達式 | 範例 | 描述 | | -------- | -------- | -------- | -------- | | and | a and b | (a and b) 回傳 False | 如果 a 跟 b 都是 True,則 (a and b) True。然而只要其中一方為 False,(a and b) 就是 False。 | | or | a or b | (a or b) 回傳 True | 如果 a 或 b 其中一個為 True,則 (a or b) True。然而只要兩方皆為 False,(a or b) 就是 False。 | | not | not a | not(a and b) 回傳 True | 如果 a 為 True,回傳 False。如果 a 為 False,回傳 True。 | not 邏輯運算子你可以把它想成是:「與結果相反的結果」,像是 a 為 True,再加上一個 not,就能讓它變成 False。 以下是使用 IDLE shell 介面操作的範例(2024/04/26 補): ```python= >>> a = True >>> b = False >>> print(a and b) False >>> print(a or b) True >>> print(not(a and b)) True >>> print(not(a or b)) False ``` ### 成員運算子(Membership operator) --- :::success 這樣理解就懂了: 成員運算子 = 檢查某個物件有沒有在序列裡面 物件可以是 123456,也可以是 "string"、[1,2,3,4,5]、(1,2,3) 等等這些資料型態。 序列(sequence):list、tuple、range ::: 在成員運算子中,總共就兩個運算子:in、not in,主要是用來判斷某變數是否存在於一個序列(sequence)當中。序列有三種基本類型:list、tuple、range。 假設有變數 x, y = 1, [1,2,3,4,5,6,7],我們想知道 x 是否在 y 序列當中,就可以使用 in 運算子來判斷。 print(x in y),結果顯示 True。 print(x not in y),結果顯示 False。 | 運算子 | 描述 | 範例 | | -------- | -------- | -------- | | in | 如果在指定的序列中尋找到該值,回傳 True,否則回傳 False。 | x in y | | not in | 如果在指定的序列中沒有尋找到該值,回傳 True,否則回傳 False。 | x not in y | 以下是使用 IDLE 介面操作的範例(2024/04/26 補): ```python= >>> x, y = 1, [1,2,3,4,5,6,7,8,9] >>> print(x in y) True >>> print(x not in y) False ``` ### 身分運算子(Identity operator) --- :::success 這樣理解就懂了: 身分運算子 = 判斷兩個物件裡面誰是一樣或不一樣的。 ::: 身分運算子和成員運算子一樣具有兩種運算子,成員運算子是判斷一變數是否存在於另一變數的序列當中,而身分運算子就是判斷 x y 之間是否存在於同一物件之中。 | 運算子 | 描述 | 範例 | | -------- | -------- | -------- | | is | 判斷 x 和 y 是否為相同的物件。 | x is y | | is not | 判斷 x 和 y 是否為不相同的物件。 | x is not y | 以下是一個範例: ``` x = [1,2,3] y = [1,2,3] z = x print(x is y) # False print(x is z) # True ``` 至於物件是什麼?在 Python 中,我們需要知道的是:「所有的資料都是物件」,另外,物件具備下列三個性質: 1. id 號碼 2. type 型態 3. value 數值 id() 為我們物件的 id 號碼,這個函數意謂指向物件的記憶體位址。 type() 在我們之前的章節有介紹過,能夠判斷一個物件的資料型態是什麼。 至於 value 的部分,我們可以使用 print() 來打印出物件的數值。 所以當使用 is 運算子判斷兩變數是否為相同物件時,若為相同物件,那麼他一定要滿足三條件,如上述所說:記憶體位址(id())、資料型態(type())、數值(value)。 條件控制(Condition) --- 在日常生活中,我們經常會面臨各種選擇,比如說:「如果」今天下雨,那麼就不出門;「如果」今天沒下雨,那麼就出門。我們將這個事件繪製成一個流程圖,會變成下面這樣: ![image](https://hackmd.io/_uploads/HJNc3nWa6.png) 圖源:[菜鳥教程](https://www.runoob.com/python3/python3-conditional-statements.html) 在 Python 中的條件語句,我們分別使用 if(如果)、elif(否則如果)、else(否則)。 在 Python 當中,不與以往程式語言同樣使用 else if,而改用為 elif 作為 else if,這點須注意。 另外,以下三點是在撰寫條件語句時需要注意的事項: 1. 每個條件語句最後都要使用冒號`:`,表示接下來是滿足條件後要執行的語句區塊。 2. 必須使用縮排(按tab鍵來進行縮排)來劃分語句塊,相同縮排數的語句在一起組成一個語句塊。 3. 在 Python 中沒有switch...case語句,但在 Python 3.10 版本加入了 match...case,功能也類似,詳見下文。 至於縮排的部分,我們只要按下鍵盤最左方的 tab 鍵即縮排,然後 shift + tab 進行退排,退縮一行。 以下是個範例: ```python= a = 10 if a == 10: print(a) b = 5 if a != b: print(b) ``` 到了條件控制的部分,我們就能夠妥善運用前面所學的「比較運算子」,在以上範例中,我們用到了「==」、「!=」兩種比較運算子。 接下來我們來做一個關於狗的年齡之範例: ```python= age = int(input("請輸入你家狗的年齡: ")) print("") if age <= 0: print("請輸入正確的數值!") elif age == 1: print("相當於 14 歲的人。") elif age == 2: print("相當於 22 歲的人。") else: print("對應人類年齡: ", 22 + (age - 2) * 5) # 退出提示 print("") input("點擊 enter 鍵退出") ``` (2024/08/03補充):首先判斷 age 是否小於等於 0,不是的話,也就是條件不成立,才會繼續走下去(直接到第一個 elif 再次判斷),再次判斷一次,一樣第一個判斷 age 是否等於 1,不是的話,以此類推下去。 而最後 else 表示以上條件全部都不合,可能 age 是 > 2(不含等於)的,才會執行 `print("對應人類年齡: ", 22 + (age - 2) * 5)`。 我們對於 if、elif、else 條件語句熟悉以後,我們再來學習巢狀條件判斷(也稱為嵌套:nested)。 什麼是巢狀條件判斷呢?簡單來說就是一個 if 下面,還有一個 if,以此類推。像是這樣: ``` if a: if b: if c: ``` 接下來我們來做一個有關於巢狀條件判斷的程式: ``` num = int(input("請輸入一個數字:")) if num % 2 == 0: if num % 3 == 0: print("你輸入的數字能夠整除 2 和 3") else: print("你輸入的數字能夠整除 2 ,但不能整除 3") else: if num % 3 == 0: print("你輸入的數字能夠整除 3,但不能整除 2") else: print("你輸入的數字不能整除 2 和 3") ``` 可以看到我們的取模(%)能夠應用到這種整除、判斷因數的程式上面,待後續我們教到迴圈時,會進一步帶各位來用程式解決質因數的問題。 APCS 實作題練習 --- APCS 是什麼?大學程式設計先修檢測,主要檢測考生程式設計能力,具有相當的公信力,能夠作為各大學資工、資管系等的選才依據。 若你為高中生,而且志向跟我一樣是想要朝著資工系前進者,我會建議你報考,但程式設計基礎一定要打好。APCS 分為觀念題以及實作題,觀念題主要是以 C 語言為主,實作題可選擇四種程式語言進行撰寫,如 C/C++、Python、Java。實作題我會建議你使用你習慣、熟悉的語言,但為了方便我反而會選擇 Python。 問題來了,APCS 主要都是在考哪些東西呢? 1. 基礎程式設計判讀能力 2. 演算法(排序、搜尋、鏈結串列、佇列、動態規劃DP(實作會用到)等) 3. 遞迴(這個非常愛考,務必將觀念搞清楚) 4. 尋找程式規律 好,話不多說,我們來搬上今日的最後一道菜了,以下是 APCS 2016 年 10 月實作第一題:三角形辨別 --- 三角形除了是最基本的多邊形外,亦可進一步細分為鈍角三形、直角三角形及銳角三角形。若給定三個線段的長度,透過下列公式運算,即可得知此三線段能否構成三角形,亦可判斷是直角、銳角和鈍角三角形。 提示:若a、b、c為三個線段的邊長,且c為最大值,則   若 a+b ≦ c     ,三線段無法構成三角形   若 a×a+b×b < c×c  ,三線段構成鈍角三角形(Obtuse triangle)   若 a×a+b×b = c×c  ,三線段構成直角三角形(Right triangle)   若 a×a+b×b > c×c  ,三線段構成銳角三角形(Acute triangle) 請設計程式以讀入三個線段的長度判斷並輸出此三線段可否構成三角形?若可,判斷 並輸出其所屬三角形類型。 --- 輸入說明: 輸入僅一行包含三正整數,三正整數皆小於 30,001,兩數之間有一空白。 --- 輸出說明 輸出共有兩行,第一行由小而大印出此三正整數,兩字之間以一個空白格間格,最後 一個數字後不應有空白;第二行輸出三角形的類型: 若無法構成三角形時輸出「No」; 若構成鈍角三角形時輸出「Obtuse」; 若直角三角形時輸出「Right」; 若銳角三角形時輸出「Acute」。 --- 提示 : (範例一說明) a×a + b×b = c×c 成立時為直角三形。 (範例二說明) 邊長排序由小到大輸出, a×a a×a + b×b > c×c 成立時為銳角三形。 (範例三說明) 由於無法構成三角形,因此第二行須印出「No」。 評分說明:輸入包含若干筆測試資料,每一筆測試資料的執行時間限制 (time limit) 均為1秒,依正確通過測資筆數給分 --- 更多詳情請至:https://zerojudge.tw/ShowProblem?problemid=c294 以下是我個人的解題思路: 第一行我們寫 `a = [int(i) for i in input().split()]`,這個稱為列表推導式,由於我們還沒學到,所以就先寫給你們看,今天的重點著重在於運算子及條件控制的部分。 之後就照著題目敘述來構成條件語句,其實這題蠻簡單的。 至於排序函數的部分,由於我們尚未學到,我就先在這邊提供:sorted(),括號裡面填入要被排序的序列。 到最後輸出的部分,如果我們直接寫 print(a) 會有列表的中括號及逗號,我們可以這樣寫,使其消失:`print(" ".join(str(i) for i in a))` 或者是這樣寫:`print(*a)` 總結 --- ### 資料型態轉換 --- * 隱式轉換(Implicit Conversion):Python 會自動將一種資料型態轉換為另一種,通常是從低精度(如整數)轉換為高精度(如浮點數),以避免資料損失。 * 顯式轉換(Explicit Cast):需要使用內建函數如 int()、float()、str() 來手動將一種資料型態轉換為另一種。文章也提供了其他常用的資料型態轉換函數。 ### 運算子(Operators) --- * 算術運算子:包括加、減、乘、除、取餘數、取整除和次方等基本運算。 * 比較運算子:用於比較兩個值之間的大小、相等與否。 * 指定運算子:用於將計算結果賦值給變數,如 +=、-= 等。 * 邏輯運算子:用於處理邏輯關係,如 and、or、not。 * 成員運算子:檢查一個元素是否存在於某個序列中,如 in 和 not in。 * 身分運算子:檢查兩個變數是否引用同一個物件,如 is 和 is not。 ### 條件控制(Condition) --- * 使用 if、elif 和 else 來進行條件判斷,並根據條件執行相應的代碼。 * 巢狀條件判斷:即在一個 if 語句中嵌套另一個 if 語句,不斷的 if 下去。 好啦,以上就是今天的內容,沒想到一口氣寫了這麼多呢XD,下列是一些參考資料: 參考資料 === [類型轉換 - 維基百科,自由的百科全書](https://zh.wikipedia.org/zh-tw/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2) [Python3 資料類型轉換| 菜鳥教程](https://www.runoob.com/python3/python3-type-conversion.html) [Python3 運算符 | 菜鳥教程](https://www.runoob.com/python3/python3-basic-operators.html#ysf1) [Python3 條件控制 | 菜鳥教程](https://www.runoob.com/python3/python3-conditional-statements.html) [repr與str雜談———暴風雨前的輕鬆小品技術文 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10194593) [運算子 operator - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/operator.html) [c294. APCS-2016-1029-1三角形辨別 - 高中生程式解題系統](https://zerojudge.tw/ShowProblem?problemid=c294) [python如何去掉list中的中括號、二級列表中的括號、雙引號_去掉列表裡子列表的[]-CSDN博客](https://blog.csdn.net/rs_gis/article/details/116088889)