本週的PyCoder's Weekly
上分享了一篇小文章,它裏面提到的冷知識頗有意思,我稍做補充,分享給你們。html
它提到的部分問題,讀者們能夠先思考下:python
答案固然都爲否(否則就不叫冷知識了),你們能夠先嚐試回答一下,而後再往下看。函數
-----思考分割線-----編碼
好了,先來看看第一個問題。兩個相同的元組 a、b,它們有以下的關係:spa
>>> a = (float('nan'),)
>>> b = a
>>> a # (nan,)
>>> b # (nan,)
>>> type(a), type(b)
(<type 'tuple'>, <type 'tuple'>)
>>> a == b
True
>>> a is b # 即 id(a) == id(b)
True
>>> a[0] == b[0]
False
複製代碼
以上代碼代表:a 等於 b(類型、值與 id 都相等),可是它們的對位元素卻不相等。code
兩個元組都只有一個元素(逗號後面沒有別的元素,這是單元素的元組的表示方法,即 len(a)==1 )。float() 是個內置函數,能夠將入參構形成一個浮點數。htm
爲何會這樣呢?先查閱一下文檔,這個內置函數的解析規則是:對象
sign ::= "+" | "-"
infinity ::= "Infinity" | "inf"
nan ::= "nan"
numeric_value ::= floatnumber | infinity | nan
numeric_string ::= [sign] numeric_value
複製代碼
它在解析時,能夠解析先後的空格、前綴的加減號(+/-)、浮點數,除此以外,還能夠解析兩類字符串(不區分大小寫):"Infinity"或"inf",表示無窮大數;「nan」,表示不是數(not-a-number),確切地說,指的是除了數之外的全部東西。索引
前面分享的第一個冷知識就跟「nan」有關,做爲總體,兩個元組相等,可是它們惟一的元素卻不相等。之因此會這樣,由於「nan」表示除了數之外的東西,它是一個範圍,因此不可比較。文檔
做爲對比,咱們來看看兩個「無窮大的浮點數」是什麼結果:
>>> a = (float('inf'),)
>>> b = a
>>> a # (inf,)
>>> b # (inf,)
>>> a == b # True
>>> a is b # True
>>> a[0] == b[0] # True
複製代碼
注意最後一次比較,它跟前面的兩個元組剛好相反,由此,咱們能夠得出結論:兩個無窮大的浮點數,數值相等,而兩個「不是數的東西」,數值不相等。
化簡一下,能夠這樣看:
>>> a = float('inf')
>>> b = float('inf')
>>> c = float('nan')
>>> d = float('nan')
>>> a == b # True
>>> c == d # False
複製代碼
以上就是第一個冷知識的揭祕。接着看第二個:
>>> hash(float('nan')) == hash(float('nan'))
True
複製代碼
前面剛說了兩個「不是數的東西」不相等,這裏卻顯示它們的哈希結果相等,這挺違背常理的。
咱們能夠推理出一條簡單的結論:不相等的兩個對象,其哈希結果可能相等。
緣由在於,hash(float('nan')) 的結果等於 0,它是個固定值,做比較時固然就相等了。
其實,關於 hash() 函數,還埋了一個彩蛋:
>>> hash(float('inf')) # 314159
>>> hash(float('-inf')) # -314159
複製代碼
有沒有以爲這個數值很熟悉啊?它正是圓周率的前五位 3.14159,去除小數點後的結果。在早期的 Python 版本中,負無窮大數的哈希結果實際上是 -271828,正是取自於天然對數 e。這兩個數都是硬編碼在 Python 解釋器中的,算是某種致敬吧。
因爲 float('nan') 的哈希值相等,這一般意味着它們不能夠做爲字典的不一樣鍵值,可是事實卻出人意料:
>>> a = {float('nan'): 1, float('nan'): 2}
>>> a
{nan: 1, nan: 2}
# 做爲對比:
>>> b = {float('inf'): 1, float('inf'): 2}
>>> b
{inf: 2}
複製代碼
如上所示,兩個 nan 鍵值在表示上如出一轍(注意,它們沒有用引號括起來),它們能夠共存,而 inf 卻只能歸併成一個,再次展現出了 nan 的神奇。
好了,兩個很冷的小知識分享完畢,背後的緣由都在於 float() 取浮點數時,Python 容許了 nan(不是數)的存在,它表示不確切的存在,因此致使了這些奇怪的結果。
最後,咱們做下小結:
參考資料: