Python字典中循环(for循环)的顺序是什么?

10
我对以下输出结果感到有些困惑,我不理解执行的循环顺序。
domains = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  }

for key in domains:
    print key

这里的输出是

sk
de
no
us
hu

但不是

de
sk
hu
us
no

同样地,在这里

num = {1:"one",4:"two",23:"three",10:"four"}
for key in num:
    print key
output is
1
10
4
23

但不

1
4
23
10

感谢您的帮助


如果你真的感兴趣,可以查看我对这个问题的回答:https://dev59.com/X2ct5IYBdhLWcg3wV8Ck#12165239 - mgilson
2
从Python3.7开始,字典中的插入顺序被保留。请参阅Python文档中有关字典迭代器、iter()的信息,您还可以在Stack Overflow上找到更详细的解释 - loved.by.Jesus
5个回答

8

Python字典不保留顺序

键和值以任意顺序列出,该顺序是非随机的,在Python实现之间变化,并取决于字典插入和删除的历史记录。

在CPython中,字典实现为哈希表,以实现快速查找和成员测试,并且枚举键或值以它们在此表中列出的顺序发生; 它们被插入的位置取决于键的哈希值,以及先前是否已将任何内容哈希到同一槽中。

您必须每次显示时对键进行排序,或使用不同类型的数据结构来保留顺序。 Python 2.7或更高版本具有collections.OrderedDict()类型,或者您可以使用一个两个值元组的列表(这时单个键值对的查找将变慢)。


@mgilson:是的,这个句子的确令人困惑,可能会被误解。我会进行修正。 - Martijn Pieters
我认为第一句话有点误导性,尤其是引用部分陈述了完全相反的情况。你首先说“没有排序”,然后引用部分说明它们以“非随机的任意顺序”排列。换句话说,有一定的次序,只是不清楚这个次序是什么。这是一个小细节,但仍然有些令人困惑。 - ernie
@ernie:'不保留顺序',是吗? - Martijn Pieters
不,它们仍然保持顺序。如果您多次循环遍历数组,则顺序将保持一致(因此从文档中得出的非随机性)。也许应该只是引用,并强调“任意顺序但非随机”。 - ernie
@ernie -- 我认为说它们没有顺序是可以的。这是一种非常常见的表达方式,意思是如果你以任何方式改变字典(包括创建它),就不能依赖于顺序。Martijn -- "不保留顺序" 是我认为可以表达得最好的了。 - mgilson

7

Python的字典没有顺序。但是,您可以使用sorted(domains)函数指定顺序。默认情况下,它使用键进行排序。

for key in sorted(domains):
    print key

将会产生
de
hu
no
sk
us

如果你想按值排序,可以使用类似于sorted(domains.items(), key = lambda(k, v): (v, k))的方法。

6

顺序未指定,但在字典未被修改的情况下保证顺序不变。

您可以在迭代时对键进行排序:

for key in sorted(domains):
    print key

最后,需要注意的是Python的新版本中有一个collections.OrderedDict,它可以保留插入顺序


2

2

按照定义,字典没有顺序。这将使其处于危险的“未定义行为”区域 - 在任何你编写的程序中依赖它不是一个好主意,因为它可能会在不同的实现/实例之间突然改变。即使它现在恰好按照你想要的方式运作…它也会在以后给你留下一个地雷。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接