雜記:Python 兩坑

近日寫代碼又遇到兩個 Python 的坑,覺得值得記錄。

遞歸傳參問題

Python 裏傳參的實現是 assignment,但由於 Python 裏都是對象,除了幾個基本類型,assignment 基本都是引用的賦值,因此在遞歸裏,你傳的參數很可能就被下一層修改掉,例如:

def some_func(A):
    # do your routines
    some_func(A)

如果這個A是個 mutable 的對象,而你的函數裏對A有修改,那每一層遞歸都是修改同一個對象A

我是在寫一個解數獨的程序時發現這個問題的。這個程序裏有將 Numpy ndarray 作爲遞歸函數的參數,因此它在遞歸過程中被各種修改,完全亂了套。最後把調用遞歸傳入A的地方換成A.copy()就解決了問題。

浮點計算精度問題

這個問題本應是幾乎所有編程語言的問題,因爲計算機不能精確表示大多數浮點數,例如經典的0.1 + 0.2 != 0.3。但這個問題在 Python 裏其實可以得到解決,就是使用 fraction 模塊。我們將所有有理浮點數都表示爲分數,就能完全保證計算過程中精度不會丟失。

# 使用 float 會丟失精度
>>> x = 0.1
>>> x == x * 3 / 3
False

# 使用 Fraction 則不會
>>> from fraction import Fraction
>>> x = Fraction('0.1')
>>> x == x * 3 / 3
True

注意,這裏是Fraction('0.1')而不是Fraction(0.1),後者還是丟失精度的,因爲0.1這個字面量在 Python 裏本身就不是準確的0.1,所以只能用字符串。

(本文完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章