1 引言
日常工作闲暇之余,我最喜欢的活动之一就是在 Stack Overflow 上闲逛, 那里有很多关于 Python 的有趣问题。的确,有些问题在我们的生活中可能永远不会遇到。然而,背后的知识却相当有趣,甚至比问题本身更有趣。
在本文中,我将挑选 Python 中的一些“神秘”行为并尝试解释它们。希望这些知识能够给大家带来一些不一样的乐趣. 😃
2 神秘的字典key
你知道 Python 中的字典可以使用任何哈希对象作为键吗?是的,这意味着我们有时甚至可以使用数字作为键。有人可能认为这是一个“好”的主意,因为这样我们可以采用形如my_dict[1+1],在字典的key中使用表达式。不,最好不要这样使用,我将证明给你看.
举例:
让我们定义一个使用整数、浮点数和字符串作为键的字典。它们的含义都是“1”。如下所示:
my_dict = {
1: 'one (integar)',
'1': 'one (string)',
1.0: 'one point zero (float)'
}
现在,让我们尝试使用键来获取值。
my_dict[1]
my_dict['1']
my_dict[1.0]
运行结果如下:
仔细观察上述输出,第一个结果不对,看起来 my_dict[1] 的值已被 my_dict[1.0] 覆盖。让我们调换下字典里key值出现的先后次序。
my_dict = {
1.0: 'one point zero (float)',
1: 'one (integar)',
'1': 'one (string)'
}
运行结果如下:
这一次,my_dict[1] 的值覆盖了 my_dict[1.0]。因此,后来定义的将覆盖前一个。这意味着key值 1 和 1.0 是相同的。
3 相关解释
我们先来看看Python官方文档:
hash(object)
Return the hash value of the object (if it has one). Hash values are integers. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0).
上述官方文档基本上已经说明了原因。我们传入的字典的键将被散列成哈希值进行比较,不幸的是,某些不同类型的哈希值是相同的。我们可以通过以下语句验证这一点。
print(hash(1))
print(hash(1.0))
print(hash('1'))
运行结果如下:
事实上,1.0 == 1在 Python 中是 True。因此,必须实现散列函数以确保 hash(1.0) == hash(1)。字典键的神秘行为是其“副作用”。
综上所述,回到问题本身你还认为用表达式作为字典键可以吗?不,这仍然是一个坏主意。让我们看看下面的例子。
print(hash(10.0 - 9.2))
print(hash(0.8))
运行结果如下:
因此,可以推测以下示例也将不会起作用。
my_dict = {0.8: 'zero point eight'}
my_dict[10.0 - 9.2]
运行结果:
这一次,这两个哈希函数的值是不同的。为什么?他们不是同一个数字0.8吗? 当然不是. 10.0 - 9.2 实际上不完全是 0.8。这是所有平台上典型的二进制浮点数运算问题。 Python 给出了文档来阐明这个问题。
因此,请不要使用数字作为字典的键。
4 总结
本文重点介绍了Python中的神秘行为之不要使用数字作为字典的键的原因,并给出了相关解释和完整的示例.
您学废了吗?
关注公众号《AI算法之道》,获取更多AI算法资讯。
参考链接