本周的PyCoder's Weekly
上分享了一篇小文章,它里面提到的冷知识颇有意思,我稍做补充,分享给你们。html
它提到的部分问题,读者们能够先思考下:python
答案固然都为否(否则就不叫冷知识了),你们能够先尝试回答一下,而后再往下看。函数
-----思考分割线-----编码
好了,先来看看第一个问题。两个相同的元组 a、b,它们有以下的关系:翻译
>>> 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(不是数)的存在,它表示不确切的存在,因此致使了这些奇怪的结果。
最后,咱们做下小结:
参考资料:
https://docs.python.org/3/library/functions.html#float
https://www.pythondoeswhat.com/2019/09/welcome-to-float-zone.html
公众号【Python猫】, 本号连载优质的系列文章,有喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写做、优质英文推荐与翻译等等,欢迎关注哦。</type></type>