关于Python浮点数哪些冷知识

最近遇到个问题:
若两个元组相等,即a==b且     ai   sb,那么相同索引的元素(如a[0]、b[0])是否必然相等?
若两个对象的hash结果相等,即hash(a)==hash(b),那么它们是否必然相等呢?

大家可以先尝试回答一下,然后再往下看
先来看看第一个问题。两个相同的元组a、b,它们有如下的关系:

a=(float(‘nan’),)
b=a
a#(nan,)
b#(nan,)

type(a),type(b)
(‘tuple’>,‘tuple’>)

a==b
True

aisb#即id(a)==id(b)
True

a[0]==b[0]
False

以上代码表明:a等于b(类型、值与id都相等),但是它们的对位元素却不相等。

两个元组都只有一个元素(逗号后面没有别的元素,这是单元素的元组的表示方法,即len(a)==1)。float()是个内置函数,可以将入参构造成一个浮点数。

为什么会这样呢?先查阅一下文档,这个内置函数的解析规则是:

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
aisb#True
a[0]==b[0]#True
它在解析时,可以解析前后的空格、前缀的加减号(+/-)、浮点数,除此之外,还可以解析两类字符串(不区分大小写):“Infinity"或"inf”,表示无穷大数;“nan”,表示不是数(not-a-number),确切地说,指的是除了数以外的所有东西。

前面分享的第一个冷知识就跟“nan”有关,作为整体,两个元组相等,但是它们唯一的元素却不相等。之所以会这样,因为“nan”表示除了数以外的东西,它是一个范围,所以不可比较。

作为对比,我们来看看两个“无穷大的浮点数”是什么结果:

a=(float(‘inf’),)
b=a
a#(inf,)
b#(inf,)

a==b#True
aisb#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(不是数)的存在,它表示不确切的存在,所以导致了这些奇怪的结果。

最后,我们作下小结:

包含float(‘nan’)的两个元组,当做整体作比较时,结果相等;两个相等的元组,其对位的元素可能不相等

float(‘nan’)表示一个“不是数”的东西,它本身不是确定值,两个对象作比较时不相等,但是其哈希结果是固定值,作比较时相等;可用作字典的键值,而且是不冲突的键值

float(‘inf’)表示无穷大的浮点数,可看作确定的值,两个对象做比较时相等,其哈希结果也相等;可用作字典的键值,但是会产生冲突

float(‘nan’)的哈希结果为0,float(‘inf’)的哈希结果为314159
编辑:hfy

关于Python浮点数哪些冷知识_设计制作_MEMS/传感技术
63
151
0
58

相关资讯

  1. 1、《悬崖之上》行走在悬崖边缘的英雄,心中长存光明3373
  2. 2、陈赫为《爱情公寓》发话,脱口而出的一句话,让网友哑口无言3687
  3. 3、杨紫为父亲“零片酬”出演该影片,却意外获得多个奖项和16亿票房1463
  4. 4、香港票房:《永不停歇》夺冠《分歧者》居亚1600
  5. 5、他当年出演《红海行动》大火,如今一病不起,身边无人照顾898
  6. 6、张柏芝在机场晒出行照片,7人上镜,工作室:全员大集合!4886
  7. 7、《大轰炸》上映前夕黑幕被曝光!全明星豪华阵容也挽救不了票房!3926
  8. 8、《新白发魔女传》将登芒果台8400万超天价成交2700
  9. 9、比《超人总动员2》更好看?应该就是它了!736
  10. 10、包贝尔亮相吐槽大会,李诞池子纷纷缺席,网友直呼这是要凉凉吗?2064
全部评论(0)
我也有话说
0
收藏
点赞
顶部