我一開始是這樣做的:
def swap(a, b):
tmp = a
a = b
b = a
x = 3
y = 5
swap(x,y)
print(x, y) # 結果印出 x是3 y是5
這樣寫就好像回到剛學程式語言,C語言裡的"call by value" vs "call by reference"時的範例
因為我印象中好像Python變數都是指向object,所以先當作都是 call by reference
結果是x, y值並沒有改變...
直接說答案,使用Python想交換兩變數的值正確簡短的做法可以這麼做:
x = 3
y = 5
x ,y = y, x
print(x, y) # >> 5,3
怎麼跟想的不一樣...於是就去Google啦~
Immutable vs Mutable
首先看看下面的程式碼:
x=2
print("x=",x," id=",id(x)) # >> x=2, id=93973909193040 black
x=3
print("x=",x," id=",id(x)) # >> x=3, id=93973909193016 red
圖解來看其實 x = 2 是將 x 指向了值是 2 的 int 物件,執行到 x = 3 時則改成指向另外值是 3 的 int 物件
所以下面的程式碼不能利用w修改q值:
q = 1
w = q # w, q id 是相同的
w = 3
print(q,w) # q還是1, w則是3
那當然會有mutable (changeable in-place ) object存在,像是 list、dictionary
下面的code就可利用w指向相同的list來修改q值:
q = [1, 2, 3]
w = q
w[0] = 3
print(q) # >> [3,2,3]
assgin "="對於immutable object不能改value,而是會創造一個新的物件(所以id會不一樣),mutable object則是改value,不需新的物件產生
回到上面的swap()為什麼不可行
def swap(a, b):
tmp = a
a = b
b = a
x = 3
y = 5
swap(x,y)
print(x, y) # 結果印出 x是3 y是5
其實swap裡就只是幾個變數tmp, a, b改對到x對到的int物件或y對到的int物件,根本不會動到x, y 對應的物件
補充
另外,在mutable object的狀況時要怎麼只存值呢?
像下面的code我們保存 t 這個 list 進 tt list裡,但之後若修改 t 連帶的也動到 tt 裡的值 (因為其實它們存取是同一物件) (這大概也是寫python code一開始容易不小心犯的錯):
t = [1,2,3]
tt = []
tt.extend(t)
t[0] = 2
print(tt) # [2,2,3]
若只想存值,而非要存物件,可以這麼寫:
t = [1,2,3]
tt = []
tt.extend(t[:])
t[0] = 2
print(tt) # [1,2,3]
如此就算修改t也不會讓tt內的值改變了,或是可以使用 copy() 函式之類的,這通常就是會只複製值
你的swap function 寫錯啦, 最後一個應該寫成b=tmp 才對, 不是b=a, 寫b=a 的話, 上一行a=b, b=a 會變成 a,b 都變成 b
回覆刪除def swap(a, b):
tmp = a
a = b
b = a