python dict implementation details
我有一个关于Python字典实现的问题。
似乎python将维护所有键的搜索顺序,例如如果您执行以下操作
1 2 3 4 5 | a = {} a[3] = 1 a[0] = 2 a = {0:2, 3:1} |
python将自动更改我的插入顺序。正如python声称dict是无序集,我不太清楚理解为什么python会保持这样的搜索顺序。python是否通过哈希表实现dict并存储另一个是否设置为索引排序?
希望我能澄清这个问题。
谢谢你
dict的顺序完全由对象的散列函数(如果存在散列冲突,则插入顺序)决定。整数自身散列(至少到
1 2 | >>> hash(1) 1 |
(c)python实现获取对象的散列值,并使用一些位来确定表中的索引。它需要多少位取决于字典的长度。默认情况下,dict有8个可用插槽,因此数字
1 2 3 4 5 6 7 8 9 10 11 | >>> d1 = {} >>> d1[0] = 'foo' >>> d1[8] = 'bar' >>> d1 {0: 'foo', 8: 'bar'} >>> >>> d2 = {} >>> d2[8] = 'bar' >>> d2[0] = 'foo' >>> d2 {8: 'bar', 0: 'foo'} |
号
由于
当然,如果您的字典恰好有超过~5个元素,它将被调整大小(我认为是16个,但不要引用我的话),并且
1 2 3 4 5 6 7 8 9 10 | >>> d1 = {x:x for x in range(1, 6)} >>> d1[0] = 0 >>> d1[8] = 8 >>> d1 {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 8: 8} >>> d2 = {x:x for x in range(1, 6)} >>> d2[8] = 8 >>> d2[0] = 0 >>> d2 {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 8: 8} |
注意,(排序的)顺序是保留的(不是插入顺序),这意味着每个整数在哈希表中都得到了它的首选位置(没有冲突)。我认为听写机在2/3rds满时会调整大小。
注意,这纯粹是学术性的——Python规范没有说明这是如何工作的,因此它可以随时更改。请不要依赖这种行为。其中大部分可以从源代码中的注释和它旁边的文档中收集…
dict索引排序只是如何实现dict的结果,不应该依赖于它。
准确地说,python不会更改插入顺序(因为它只是定义为将项目插入dict的顺序),但是迭代顺序没有保证。
当python创建dict时,它会为8个键、值对(我认为)创建足够的空间。对于空的听写,没有一个是满的。每当您将一个项放入dict中时,python都会获取该键的散列值,而该键的散列值决定了索引是什么。
如果您希望迭代顺序与插入顺序相同,请签出ordereddict。