你绝对想不到的Python中的神秘行为(一)

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算法资讯。
在这里插入图片描述

参考链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值