tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4 );
当用于字典中的键时,python如何在元素大小变化时决定键的大小?
答案 0 :(得分:4)
Python词典无需知道密钥的大小。 Python字典如果提供__hash__
和__eq__
特殊方法,则接受任何对象作为键。 Python通过key == another
找到匹配的密钥,内部调用key.__eq__(another)
。这也意味着,您可以拥有一个字符串,其中包含字符串,整数,1和100个元素的元组作为键。
为了加快速度,字典将这些密钥组织到一个哈希表中,该哈希表使用用hash(key)
计算的哈希码来划分密钥;内部hash(key)
来电key.__hash__()
;哈希码是一个满足两个规则的简单整数:
hash(key) == hash(another)
if key == another
key != another
最好(但不是在每种情况下)hash(key) != hash(another)
此外,Python hash(x)
必须在x
的生命周期内保持不变,这意味着x
与其他对象的相等性也不得更改。
元组同时包含__eq__
和__hash__
:
>>> t = ('physics', 'chemistry', 1997, 2000)
>>> hash(t)
1710411284653490310
>>> u = ('physics', 'chemistry', 1997, 2000) # another tuple
>>> t is u # they are not the same object
False
>>> hash(t) == hash(u)
True
>>> t == u
True
现在,Python甚至根本不需要使用哈希代码来查找字典中的对象,只需找到一个具有匹配键的元素,将每个键与==
的给定键进行比较。但这意味着在具有n
个密钥的字典中,平均n / 2
必须进行比较才能找到密钥。使用散列技巧,我们可以缩小要比较的键集,理想情况下总是最多1或少数,因此字典中的查找应该同样快,无论它是小还是大。
现在,与元组不同,Python中的list
是一个可变值,对于它来说,不可能提供一个不变的哈希码,以后将满足上面给出的2个规则。因此Python根本没有定义它:
>>> [].__hash__ is None
True
同样,如果将其用作字典键,则会出现异常:
>>> {[]: 42}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
答案 1 :(得分:3)
当元素大小变化时,python如何决定键的大小?
简单的答案是它没有:Python允许使用异构密钥的字典。这比不同大小的元组要广泛得多:
In [15]: d = {}
In [16]: d[42] = 'foo'
In [17]: d['bar'] = -1
In [18]: d[(1, 2, 3)] = {}
In [19]: d
Out[19]: {42: 'foo', 'bar': -1, (1, 2, 3): {}}
任何hashable对象,无论其类型如何,都可以用作任何字典的键。
答案 2 :(得分:1)