#45351: python 你討厭相同的邏輯要寫兩次嗎? 可以利用 python 的函數特性 - pass by assignment


sam851015@gmail.com (多挖鼻孔有益身心健康)

學校 : 臺中市立惠文高級中學
編號 : 277705
來源 : [123.192.228.253]
最後登入時間 :
2025-03-11 12:39:29
o923. 陣列運算 (Array) -- TOI練習賽202411新手組第3題 | From: [123.192.228.253] | 發表日期 : 2025-02-17 18:44

這題跟著題目指示操作陣列就可以了,只考驗你對基礎語法的熟悉度而已。

就算不使用這篇文使用的特性依然能寫,比較囉嗦而已

如果你完全寫不出來,那這篇文可能不適合你。

 

你有想過函數的傳入參數在背後是如何運作的嗎? 不同語言有不同的運作方式

常見的就是 pass-by-value, pass-by-reference...... 之類的

 

pass by value

是 c++ 的預設方式(可以改),傳入參數時,會複製一份一樣的資料用在函數內。

具體一點描述的話....

 

小明有一張紙,上面寫的是他的作文;

小美想參考一下他的作文,於是小明影印了一份一樣的作文給小美;

小美閱讀後發現錯字,把錯字用紅筆修改一下;

小美把作文還給小明,現在一共有兩份作文,一份是小美修改過的,一份是小明的原稿。

 

 

pass by reference

則是傳入該物件的「記憶體位置」,什麼意思? 意思是使用這種方式傳入參數的話,解釋器不會複製一份新的東西,而是傳入一個地址,告訴函數「你要的東西放在這,他長這樣」

如果你修改那個地址的東西,就會整組一起改,所有知道這個地址的人都可以注意到他的內容被改掉了。

具體一點的描述的話.......

 

小明有一張紙,上面寫的是他的作文;

小美想參考一下他的作文,於是小明告訴小美作文的位置(釘在布告欄上);

小美去布告欄找到了小明的作文,發現上面寫的是小美的黑歷史,於是小美把裡面的內容全部塗黑;

小美直接改的是原始資料,也沒有第二份了,大家去布告欄只能看到小美修改後的結果(黑歷史被竄改)。

 

 

pass by assignment

python 是哪一種? 兩種都不是,雖然上述兩種的特性 python 都有一些,但卻又不完全相同。

python 是 pass by assignment

傳入參數時,實際上傳入的是地址,這部份和 reference 相同,但要修改時,會先檢查這個物件是否為可變物件(mutable object)

如果是不可變的,例如 int, tuple, float, str,則會先複製一份再修改;

反之如果是可變的,例如 list, set, dict,則不會再複製,而是直接修改該位置的內容。

舉例來說的話......

 

小明有一張紙,上面寫著一篇作文;

小美想看看作文的內容,於是小明告訴他作文放在布告欄上(傳入地址);

小美去布告欄上找到那篇作文,發現上面全是小美的黑歷史,所以她想改掉那篇作文,但得先看看這篇作文有沒有辦法改;

  • 小美發現作文是被護貝過的,根本改不了 (不可變物件),所以她影印了一份新的,然後把影印的那份全部塗黑,現在有兩份作文,一份被塗黑,另一份則是沒有任何變化的原稿,大家去布告欄還是能看到小美的黑歷史,至於被塗黑的版本......可能塞在小明的嘴裡吧
  • 小美發現作文沒有被保護,所以她直接把原稿塗黑了,大家到布告欄後只能看到一份被塗黑的原稿。

 

可以透過簡單的程式觀察變化

傳入不可變參數

 
def func1(arg):
  print(a is arg) # true
  arg = 20
  print(a is arg) # false
    return arg

a = 10
b = func1(a)
print(a is b)   # False
print(a == b)   # False

 

傳入可變參數

def func2(arg):
  print(c is arg) # true
  arg.append(10)
  print(c is arg) # true
    return arg

c = [1, 2, 3]
d = func2(c)
print(c is d)   # true
print(c == d)   # true

 

註: is 是 python 用來檢查兩個變量是否都指向同一個記憶體位置的語句,和 == 不同喔

 

現在你知道這個特性了,那就利用這個特性讓你的程式碼更簡潔吧。

 

參考答案: gist

 

參考資料:

python - How do I pass a variable by reference? | Stack Overflow

Programming FAQ | Python 3.13.2 documentation

關於 Assignment(賦值) 這檔事. Assign Value 這稀鬆平常的事情,卻常常會暗埋陷阱 | by Les Lee | 一個小小工程師的隨手筆記 | Medium

 

 
ZeroJudge Forum