Qio*_*Liu 2 python dictionary tuples immutability
python 中的元组可以有不同类型的元素。例如:
tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4 );
Run Code Online (Sandbox Code Playgroud)
当用于字典中的键时,当元素大小变化时,python如何决定键的大小?
Python 字典不需要知道键的大小。Python 字典接受任何对象作为键,前提是它提供了__hash__和__eq__特殊方法。Python 通过 找到匹配的键key == another,它在内部调用key.__eq__(another). 这也意味着,您可以拥有一个同时包含字符串、整数、1 和 100 个元素的元组作为键的字典。
为了加快速度,字典将这些键组织成一个哈希表,该表使用计算的哈希码hash(key)来划分键;内部hash(key)调用 key.__hash__();哈希码是一个满足两个规则的简单整数:
hash(key) == hash(another)如果key == anotherkey != another那么最好(但不是在所有情况下)hash(key) != hash(another)此外,在 Pythonhash(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
Run Code Online (Sandbox Code Playgroud)
现在,Python 甚至根本不需要使用哈希码在字典中查找对象,它只需要找到一个具有匹配键的元素,将每个元素与给定的键进行比较==。但这意味着在具有n键的字典上,平均n / 2必须进行比较才能找到键。使用散列技巧,我们可以缩小要比较的键集,理想情况下始终为 1 或最多为少数,因此无论大小,字典中的查找都应该同样快。
现在,与元组不同list,Python 中的 a 是可变值,因此不可能提供将来也满足上述 2 条规则的不变哈希码。因此 Python 根本没有定义它:
>>> [].__hash__ is None
True
Run Code Online (Sandbox Code Playgroud)
同样,如果将其用作字典键,则会出现异常:
>>> {[]: 42}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)
当元素大小变化时,python如何决定key的大小?
简单的答案是它没有: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): {}}
Run Code Online (Sandbox Code Playgroud)
任何可散列对象,无论其类型如何,都可以用作任何字典的键。