我不明白循环字典或在 python 中设置是如何按“任意”顺序完成的。
我的意思是,它是一种编程语言,所以语言中的所有内容都必须 100% 确定,对吗? Python 必须有某种算法来决定选择字典或集合的哪一部分,第一、第二等等。
我错过了什么?
最佳答案
Note: This answer was written before the implementation of the
dict
type changed, in Python 3.6. Most of the implementation details in this answer still apply, but the listing order of keys in dictionaries is no longer determined by hash values. The set implementation remains unchanged.
'foo'
和 'bar'
例如,假设表大小为 8 个插槽。在 Python 2.7 中,hash('foo')
是 -4177197833195190597
, hash('bar')
是 327024216814240868
. Modulo 8,这意味着这两个键插入插槽 3 和 4,然后:>>> hash('foo')
-4177197833195190597
>>> hash('foo') % 8
3
>>> hash('bar')
327024216814240868
>>> hash('bar') % 8
4
>>> {'bar': None, 'foo': None}
{'foo': None, 'bar': None}
'foo'
之前列出'bar'
.bar
和 baz
但是,具有正好相隔 8 的哈希值,因此映射到完全相同的插槽 4
:>>> hash('bar')
327024216814240868
>>> hash('baz')
327024216814240876
>>> hash('bar') % 8
4
>>> hash('baz') % 8
4
>>> {'baz': None, 'bar': None}
{'bar': None, 'baz': None}
>>> {'bar': None, 'baz': None}
{'baz': None, 'bar': None}
dict
作品,或拿起一份 Beautiful Code ,其中包括由 Andrew Kuchling 编写的关于实现的一章。dict
保持插入顺序的实现,并且启动速度更快,内存效率更高。新实现不是保留一个大的稀疏表,其中每一行都引用存储的散列值以及键和值对象,而是添加了一个较小的散列数组,该数组仅引用单独的“密集”表中的索引(一个只包含尽可能多的行)因为有实际的键值对),并且恰好是按顺序列出包含的项目的密集表。见 proposal to Python-Dev for more details .请注意,在 Python 3.6 中,这被视为实现细节,Python-the-language 没有指定其他实现必须保留顺序。这在 Python 3.7 中发生了变化,这里的细节是 elevated to be a language specification ;对于任何与 Python 3.7 或更高版本正确兼容的实现 必须复制这种保留顺序的行为。明确地说:此更改不适用于集合,因为集合已经具有“小”哈希结构。OrderedDict
class ,dict
的子类它添加了一个额外的数据结构来记录 key 顺序。以一定的速度和额外的内存为代价,这个类会记住你插入 key 的顺序;列出键、值或项目将按该顺序列出。它使用存储在附加字典中的双向链表来有效地保持订单最新。见 post by Raymond Hettinger outlining the idea . OrderedDict
对象还有其他优点,例如可重新排序。oset
package ;它适用于 Python 2.5 及更高版本。
https://stackoverflow.com/questions/15479928/