在旧版本的Python中,字典中的键的顺序是不确定的。这意味着当您迭代或访问字典中的键时,它们可能以不同的顺序出现。这是因为旧版本的Python使用了一种称为哈希表的数据结构来实现字典,它不保留键的顺序。如果您需要按特定顺序处理字典中的键,您可以使用collections模块中的OrderedDict类,它会保留键的插入顺序。在新版本的Python中,默认情况下字典的键是有序的,因此您可以直接迭代字典并按插入顺序访问键。

139

代码:

d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()

print l

这将打印出['a', 'c', 'b']。我不确定方法keys()如何确定l中关键字的顺序。然而,我希望能够按照"正确"的顺序检索关键字。
当然,"正确"的顺序将创建列表['a', 'b', 'c']

4
如果Python字典像大多数情况一样,它们实际上是哈希表。这意味着键的顺序不被保证或指定。特别地,它不会记住添加键的顺序。 - cHao
4
这句话的意思是,如果你在字典中循环遍历元素,那么你的程序将是不确定性的? - HelloGoodbye
5
@HelloGoodbye: 我不会说得那么绝对;这里仍然存在非常可预测的行为。每次完整的迭代都会看到每个键/值对恰好一次。在大多数语言中,你甚至会按照相同的顺序看到它们。但是,除非文档保证特定的顺序,否则你不应该指望它是你想要的顺序。(一些语言(如Perl)实际上会稍微随机一下顺序--据称是出于安全原因,但我认为这只是为了让你摆脱依赖未指定行为的习惯。:) 我不认为Python会那么恶意,但是嘛...) - cHao
1
如果字典没有被修改,那么顺序将保持不变。 来自手册的说明: “如果在调用items()、keys()、values()、iteritems()、iterkeys()和itervalues()时没有对字典进行任何修改,则列表将直接对应。这允许使用zip()创建(value, key)对:pairs = zip(d.values(), d.keys())。” - steveayre
2
@sfranky,我认为steveayre的意思是,使用不同方法获得的顺序相同,而不是与元素编写的顺序相同。 - bli
显示剩余3条评论
6个回答

214

Python 3.7+

在Python 3.7.0 中,dict 对象保持插入顺序的特性已被宣布为 Python 语言规范的官方一部分。因此,您可以依赖它。

Python 3.6 (CPython)

从Python 3.6开始,对于Python的CPython实现,默认情况下字典保持插入顺序。尽管如此,这被认为是一项实现细节;如果您想要跨其他Python实现保证插入顺序,则仍应使用{{link5:collections.OrderedDict}}。

Python >=2.7 and <3.6

当您需要一个记住插入顺序的dict时,请使用collections.OrderedDict类。


87

您可以使用 OrderedDict (需要Python 2.7或更高版本)。

此外,请注意,OrderedDict({'a': 1, 'b':2, 'c':3}) 不起作用,因为您使用 {...} 创建的字典已经忘记了元素的顺序。 相反,您应该使用 OrderedDict([('a', 1), ('b', 2), ('c', 3)])

如文档所述,在低于Python 2.7版本的情况下,您可以使用配方。


22
请记住,有序字典(OrderedDict)的顺序是按照插入顺序确定的;如果您以字母顺序插入键,则只有按字母顺序输出键。 - Hugh Bothwell
这只是他展示的一个简化例子,可能与他实际使用的方式无关。我之前遇到过一些人期望有序字典按照插入顺序返回任意插入,因此我觉得应该指出这一点。 - Hugh Bothwell
我并不认为作者在寻找一个保留插入顺序的字典。键的顺序通常更重要,可以通过自平衡二叉搜索树来实现。在C++中,我们有std::set来实现这一点。在Python中,显然没有这样的东西(内置)。 - vvaltchev

53
>>> print sorted(d.keys())
['a', 'b', 'c']
使用sorted函数对传入的可迭代对象进行排序。 .keys()方法以任意顺序返回键。

13
如果您想保留原始顺序且未排序,则此方法无效。 - Simon
如果你只需要排序一次,那很好。但如果你需要在循环中进行排序,最好使用treap或红黑树等数据结构 - 这些可以在Pypi上找到。 - dstromberg

13

这个短语已经不存在了。 - Alexander Pozdneev

12

当你想要使用它时,只需要对列表进行排序。

l = sorted(d.keys())

1
尽管顺序并不重要,因为字典是哈希表。但它的推入方式取决于顺序:
s = 'abbc'
a = 'cbab'

def load_dict(s):
    dict_tmp = {}
    for ch in s:
        if ch in dict_tmp.keys():
            dict_tmp[ch]+=1
        else:
            dict_tmp[ch] = 1
    return dict_tmp

dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))

输出:
对于字符串abbc,键为dict_keys(['a', 'b', 'c'])
对于字符串cbab,键为dict_keys(['c', 'b', 'a'])


2
Python中的字典从3.6版本开始仅按插入顺序排序查看此链接 - Crivella

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