迭代字典按排序顺序返回键

itj*_*s18 2 python dictionary

我有一个关于 python 如何处理字典中的数据的问题。假设我有一个简单的字典,其中一个数字作为键,一个数字作为值,如下所示:

a = { 5: 3, 20: 1, 1: 1, 5: 2, 100: 3, 11: 6,
     14: 1, 15: 2, 16: 4, 17: 2, 25: 1, 19: 1 }
Run Code Online (Sandbox Code Playgroud)

我想遍历这本字典并打印出键。每次我循环遍历字典(如下所示)时,它都会按升序打印键。

这就是我想要它做的,但我想知道,据我所知,为什么会发生这种情况?它每次都会自动按升序排序吗?正如您在上面的字典中看到的,键显然不是按升序排列的,但下面的输出按升序打印它们。

我只是想获得一个清晰的理解,任何帮助将不胜感激。谢谢

例子

for i in a:
    print i
Run Code Online (Sandbox Code Playgroud)

输出

1
5
11
14
15
16
17
19
20
25
100
Run Code Online (Sandbox Code Playgroud)

enr*_*cis 5

字典中的整数并不总是按键排序:

a = {2:0, 9:0}
print a.keys()  # [9, 2]
Run Code Online (Sandbox Code Playgroud)

Python 字典是哈希表,它是一种特殊的数组,其中存储值的单元格的索引是通过在key上应用特殊函数(我们称之为函数)而派生的。这样,如果您想检索特定键的,您可以再次计算该的函数,这将返回与之前相同的结果,获取存储该的索引。hashhash

hash函数将大多数类型的数据转换为整数:

print hash(1)             # 1
print hash('hello')       # 840651671246116861
print hash((2,3))         # 3713082714463740756
Run Code Online (Sandbox Code Playgroud)

每种类型都可以定义自己的方式来计算哈希值,并且int 通常返回自身:

print hash(1)             # 1
print hash(20)            # 20
print hash(1000)          # 1000
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,数字很快就会变大,我们不希望有一个包含840651671246116861个单元格的数组只是为了保存 string hello。为了避免这个问题,我们可以创建一个包含n元素的数组,然后使用散列除以的余数n作为索引

例如,如果我们想在8 个hello元素的数组中查找 的索引:

print hash('hello') % 8   # 5
Run Code Online (Sandbox Code Playgroud)

所以我们的字典会知道键的hello位于索引8处。这就是字典的实现方式。

那么,为什么{2:0, 9:0}不在键上排序呢?这是因为 Python 字典是用8 个元素创建的,并根据需要增长(更多内容请参见此处

让我们计算索引以将具有key = 2和 的数据存储key = 9在字典中n = 8

print hash(2) % 8         # 2  [hash(2) = 2 and 2 % 8 = 2]
print hash(9) % 8         # 1  [hash(9) = 9 and 9 % 8 = 1]
Run Code Online (Sandbox Code Playgroud)

这意味着包含字典数据的数组将是:

| index | key | value |
|-------|-----|-------|
|   0   |     |       |
|   1   |  9  |   0   |
|   2   |  2  |   0   |
|   3   |     |       |
|   4   |     |       |
|   5   |     |       |
|   6   |     |       |
|   7   |     |       |
Run Code Online (Sandbox Code Playgroud)

当迭代它时,顺序将是该表示中呈现的顺序,因此9将是 before 2

您可以在此处阅读有关该主题的更多信息。