除了列表和字典之外,字典键几乎可以是我们目前学到的任何数据类型。如果我们使用列表或字典作为字典键,计算机会产生一个错误:
d_1 = {5: 'int',
'5': 'string',
3.5: 'float',
False: 'Boolean'
}
print(d_1)
输出结果:
{5: ‘int’, ‘5’: ‘string’, 3.5: ‘float’, False: ‘Boolean’}`
d_2 = {[1,2,3]: 'list'}
print(d_2)```
输出结果:
TypeError: unhashable type: ‘list’
d_3 = {{'key': 'value'}: 'dictionary'}
print(d_3)
输出结果:
TypeError: unhashable type: ‘dict’
(为了解释背后发生了什么,我们将在下面解释为什么会出现这个错误。然而,理解这一点对推进这项任务并不重要,所以可以直接跳到练习上。)
为了理解上面的错误消息,我们必须简要了解一下Python在背后做了什么。当我们填充一个字典时,Python试图在后台将每个字典键转换为一个整数(即使键不是整数,而是数据类型)。Python使用hash()命令进行转换:
print(hash(4))
print(hash('four'))
print(hash(3.32))
print(hash(True))
输出结果:
4
2181486046996535831
737869762948381699
1
由于稍后我们将能够理解的原因,hash()命令没有将列表和字典转换为整数,而是返回一个错误。注意,错误消息与我们尝试使用列表或字典作为键时的错误消息相同。
print(hash([1,2,3]))
输出结果:
TypeError: unhashable type: ‘list’
print(hash({‘key’: ‘value’}))
输出结果:
TypeError: unhashable type: ‘dict’
在填充字典时,还需要确保字典中的每个键都是唯一的。如果我们对两个或多个不同的值使用相同的键,Python只保留字典中的最后一个键值对,并删除其他的键值对——这意味着我们将丢失数据:
d_1 = {'a_key': 1,
'another_key': 2,
'a_key': 3,
'yet_another_key': 4,
'a_key': 5
}
print(d_1)
输出结果:
{‘a_key’: 5, ‘another_key’: 2, ‘yet_another_key’: 4}
一个奇怪的“陷阱”是当我们将整数与布尔值混合作为字典键时。hash()命令将布尔值True转换为1,将布尔值False转换为0。这意味着布尔值True和False将与整数0和1发生冲突。字典键不再是惟一的了,在这种情况下,Python只保留最后一对键值对。
d_1 = {1: 'one', True: 'Boolean'}
d_2 = {False: 'Bool', 0: 'zero'}
d_3 = {0: 'zero', 1: 'one', 2: 'two', True: 'true', False: 'false'}
print(d_1)
print(d_2)
print(d_3)
输出结果:
{1: ‘Boolean’}
{False: ‘zero’}
{0: ‘false’, 1: ‘true’, 2: ‘two’}