Python 入門指南 5.0

單元 11 - 進一步講指派與相等運算

~~學習進度表~~

Python 中都是物件 (object) ,物件分為可變 (mutable) 與不可變 (immutable) 兩種,可變的表示可以改變其內容,像是串列 (list) 、集合 (set) 、字典 (dictionary) 都可以附加、刪除或更換元素,不可變就是不能對內容做任何修改

mutable <=> immutable

下表為目前介紹過可變的資料型態 (data type) ,這些型態名稱都是 Python 內建的識別字 (identifier)

型態名稱中文名稱
list串列
set集合
dict字典

至於其他介紹過的資料型態都是不可變的,如下表

型態名稱中文名稱
bool布林
int整數
float浮點數
complex複數
str字串
tuple序對
rangerange

簡單說,如果先後用兩個變數 (variable) 分別建立相同的不可變資料型態數值,例如下圖變數 a 跟變數 b 都是指派為整數 1

連續兩個等號判斷數值是否相等,結果是回傳 True ,關鍵字 is 則可用來判斷兩個變數是否是相同物件,結果也是回傳 Trueis 回傳 True 的原因是兩個 id() 的回傳值相同,因為 id() 會回傳物件起始的記憶體位置,既然起始的記憶體位置相同的話,那就會是相同的物件。

但是浮點數 (floating-point number) 包括可含有浮點數的複數會有點複雜,因為浮點數建立過程經過電腦模擬計算,建立一次就會模擬計算一次,也就是會重新建立一次物件,如下圖,兩個浮點數變數會是不同的物件

但是如果是將變數 a 直接指派給變數 b ,變數 a 跟變數 b 就會是相同的物件,如下圖

基本上 Python 中的數字型態都是不可變的,由於浮點數與複數都歸類為數字,再加上跟整數一樣都只有一個值,如果要改變都只能重新指派變數值。

以上是討論如將兩個變數指向相同的物件,指派運算還可以加入 if 條件檢查來決定指派的數值,例如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 設定變數 n 同時檢查型態
n = 10 if type(10) == int else None
# 印出變數 n
print(n)
# 設定變數 n 同時檢查型態
n = 10 if type(10) == str else None
# 印出變數 n
print(n)

# 檔名: assign_demo01.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月

第 2 行在指派運算後加上 if 陳述,以條件檢查整數 10 是否為整數型態,如果是,變數 n 會順利被指派為整數 10 ,否則會被指派為 None ,由於 10 是整數沒錯,所以 n 會被設定為整數 10

 2
n = 10 if type(10) == int else None

第 6 行再做一次,不過條件檢查整數 10 是否為字串 (string) 型態,這樣變數 n 就會被指派為 None

 6
n = 10 if type(10) == str else None

此例執行結果如下

$ python assign_demo01.py
10
None
$

指派還有個特殊情況,一般來說, Python 的指派都是以陳述 (statement) 為主,也就是說,等號並不能放入其他的陳述當作運算式 (expression) ,但是針對需要指派運算式的情況, Python 允許用 := 單獨寫指派運算式 (assignment expression) ,例如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 以下條件含有指派運算式
if (i := -22) > 0:
    # 如果條件為真就印出提示訊息
    print("-22 大於 0")
# if 陳述結束後印出 i
print(i)

# 檔名: assign_demo02.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月

:= 因為排列像是海象的眼睛與長牙,因此又被稱為海象運算子 (walrus operator) 。

第 2 行,這裡的指派是放到 if 陳述的條件中,先把 i 指派為 -22 ,再判斷變數 i 是否大於 0

 2
if (i := -22) > 0:

此例執行結果如下

$ python assign_demo02.py
-22
$

注意 := 必須包含在其他陳述內,不能單獨作為陳述,因此通常會用小括弧圍起來。

接下來我們回到可變的資料型態,以下用串列為例來看看指派的情況

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 設定變數 data 為串列
data = [1, 2, 3]
# 將 data 指派給 new_data
new_data = data
# 判斷 data 與 new_data 是否有相同的內容
if new_data == data:
    print("單純指派有相同的內容")
# 判斷 data 與 new_data 是否為相同的物件
if new_data is data:
    print("單純指派是相同的物件")
# 將 data 的內容拷貝給 new_data
new_data2 = data.copy()
# 判斷 data 與 new_data 是否有相同的內容
if new_data2 == data:
    print("單純拷貝有相同的內容")
# 判斷 data 與 new_data 是否為相同的物件
if new_data2 is data:
    print("單純拷貝是相同的物件")
else:
    print("單純拷貝不是相同的物件")

# 檔名: assign_demo03.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月

以上 new_data 是被 data 指派,而 new_data2 則是被 data.copy() 指派

12
new_data2 = data.copy()

兩者有何不同呢?我們先來看看執行結果如下

$ python assign_demo03.py
單純指派有相同的內容
單純指派是相同的物件
單純拷貝有相同的內容
單純拷貝不是相同的物件
$

簡單說,如果是指派,兩個變數都連結到相同的物件,因此運用任何一個變數都能操作及修改該物件,但是如果用串列的 copy() 方法再指派,那是把元素內容拷貝建立一個新的串列給被指派的變數。

所以對串列來說,如果相同的物件連結到不同的變數,那就直接用變數來指派,反之如果需要的是單純拷貝為新的物件,那就要用 copy() 方法進行拷貝。

其實以上不是很好理解,但是需要慢慢弄懂,因為這是深入 Python 程式設計總是會碰到的問題,接下來我們回到介紹模組化 (modular design) 程式設計的第二步,也就是介紹如何定義類別 (class) 。

中英文術語對照
指派運算式assignment expression
類別class
資料型態data type
字典dictionary
浮點數floating-point number
運算式expression
識別字identifier
不可變immutable
串列list
模組化modular design
可變mutable
物件object
集合set
陳述statement
字串string
海象運算子walrus operator
變數variable
重點整理
1. Python 中的物件分成可變的與不可變的。。
2. 可變的資料型態有串列、集合、字典等。
3. 不可變的資料型態有布林、整數、浮點數、複數、字串、序對、 range 等。
4. 指派運算可以加入 if-else 來檢查,提供其他的指派選項。
5. 指派運算式可以放入其他陳述中進行指派動作。
6. 對可變的資料型態,直接指派會是相同的物件,如果呼叫 copy() 後指派,就會有相同內容但是不同的物件。
問題與討論
1. 兩個變數如果有相同的內容,如何分辨兩個變數是不是同一個物件?
2. 如何對指派數值進行條件檢查,好讓指派的數值符合需求?
3. 什麼是指派運算式?指派運算式有什麼限制?
練習
1. 寫一個程式 exercise1101.py ,裡頭建立兩個空集合變數,先判斷是否有相同的內容,再判斷是否為相同的物件,如果相同就印出相對應的訊息。 參考程式碼
2. 寫一個程式 exercise1102.py ,裡頭建立兩個空字串變數,先判斷是否有相同的內容,再判斷是否為相同的物件,如果相同就印出相對應的訊息。 參考程式碼
3. 寫一個程式 exercise1102.py ,裡頭建立兩個浮點數變數,兩者都指派為 0.0 ,先判斷是否有相同的內容,再判斷是否為相同的物件,如果相同就印出相對應的訊息。 參考程式碼
4. 承接上一單元的練習 3 ,將新程式寫在 exercise1104.py 中,加入對參數重新指派並檢查參數是否為整數,如果不是整數就回傳 None參考程式碼
5. 承接上一單元的練習 5 ,將新程式寫在 exercise1105.py 中,加入對參數重新指派並檢查參數是否為整數,如果不是整數就回傳 None參考程式碼
6. 承接上一單元的練習 17 ,將新程式寫在 exercise1106.py 中,加入對參數重新指派並檢查參數是否為整數,如果不是整數就產生 None參考程式碼
7. 承接上一單元的練習 7 ,將新程式寫在 exercise1107.py 中,加入對參數重新指派並檢查參數是否為整數,如果不是整數就回傳 None參考程式碼
8. 承接上一單元的練習 18 ,將新程式寫在 exercise1108.py 中,加入對參數重新指派並檢查參數是否為整數,如果不是整數就產生 None參考程式碼
9. 承接單元 6 的練習 8 ,將新程式寫在 exercise1109.py 中,將 score 的指派放到 if 之後的條件中。 參考程式碼
10. 承接單元 7 的練習 7 ,將新程式寫在 exercise1110.py 中,將使用者輸入及判斷結束條件都放到 while 之後的條件中。 參考程式碼

上一頁 單元 10 - 函數
回 Python 入門指南 5.0 首頁
下一頁 單元 12 - 類別
回 Python 教材首頁
回程式語言教材首頁