有人知道Python内置字典类型是如何实现的吗?我的理解是它是一种哈希表,但我还没有找到任何明确的答案。
有人知道Python内置字典类型是如何实现的吗?我的理解是它是一种哈希表,但我还没有找到任何明确的答案。
这个答案适用于Python 3.6之前的版本。对于Python 3.6及以上版本,请参考下面的russia-must-remove-putin's answer。
这里是关于Python字典的所有内容,我尽力整理了一切(可能比任何人想知道的都多;但这个答案是全面的)。
从Python 3.6开始,有序方面尚未得到官方认可(为了让其他实现有机会跟上),但在Python 3.7中是官方的。
很长一段时间,它的工作方式完全如此。 Python会预先分配8个空行,并使用哈希来确定要将键值对放在哪里。例如,如果键的哈希以001结尾,则会将其粘贴在第1个(即第二个)索引处(如下面的示例所示)。
<hash> <key> <value>
null null null
...010001 ffeb678c 633241c4 # addresses of the keys and values
null null null
... ... ...
[null, 0, null, null, null, null, null, null]
我们的表格只会按照插入顺序进行填充:
<hash> <key> <value>
...010001 ffeb678c 633241c4
... ... ...
另一种节省空间的优化是实现共享键。因此,我们不再使用占用大量空间的冗余字典,而是使用重复使用共享键和键哈希的字典。你可以这样想:
hash key dict_0 dict_1 dict_2...
...010001 ffeb678c 633241c4 fffad420 ...
... ... ... ... ...
对于64位机器,这将每个额外字典的每个键节省高达16个字节。
这些共享密钥字典旨在用于自定义对象的__dict__
。为了获得这种行为,我认为您需要在实例化下一个对象之前完成填充__dict__
(参见PEP 412)。这意味着您应该在__init__
或__new__
中分配所有属性,否则可能无法获得空间节省。
然而,如果您在执行__init__
时知道所有属性,还可以为对象提供__slots__
,并保证根本不创建__dict__
(如果在父级中不可用),甚至允许__dict__
但保证您预见到的属性仍存储在插槽中。有关__slots__
的更多信息,请查看我的答案。
**kwargs
的顺序。