排序键是否由Python字典保证?

时间:2014-02-15 06:37:00

标签: python dictionary

迭代dict可以产生排序键是令人惊讶的。如果这是一种有保证的行为,它也会非常有用。

示例代码

fruits = {3: "banana",
          4: "grapes",
          1: "apple",
          2: "cherry"}

# Looping over the dict itelf
for each in fruits:
    print each, fruits[each]

输出

1 apple
2 cherry
3 banana
4 grapes


# Looping over the generator produces the same result too
for each in iter(fruits):
    print each, fruits[each]

注意:我想指出我不希望实现ordered dict。我只是想验证上面编写的代码是否是python中的正常,反复出现的行为(上面的版本2.7)

5 个答案:

答案 0 :(得分:2)

您可以继承dict并创建自己的SortedDict类,就像这样

class SortedDict(dict):
    def __iter__(self):
        return iter(sorted(super(SortedDict, self).__iter__()))

    def items(self):
        return iter((k, self[k]) for k in self)

fruits = SortedDict({3: "banana",
          4: "grapes",
          1: "apple",
          2: "cherry"})

for each in fruits:
    print each, fruits[each]

完整的工作实施是here

答案 1 :(得分:2)

From the docs:

  

键和值以任意顺序列出,这是非随机的,在Python实现中各不相同,并且取决于字典的插入和删除历史。

答案 2 :(得分:0)

对dict的迭代不能保证产生任何特定的顺序。特别地,不保证对其进行排序,不保证其处于插入顺序,它可以在相同的序列之间不同,并且它可以与解释器的一次执行不同。这是一个例子:

>>> dict.fromkeys([-1, -2])
{-2: None, -1: None}
>>> dict.fromkeys([-2, -1])
{-1: None, -2: None}

两个相同的词,两个不同的顺序。 dict不是插入键的顺序,第二个dict的键不是按顺序排列。

如果要按排序顺序迭代键,请使用

for key in sorted(d)

如果您想按插入顺序迭代按键,请使用collections.OrderedDict

答案 3 :(得分:0)

除了OrderedDict,你可以使用内置的排序函数迭代一个字典:

fruits = {3: "banana",
      4: "grapes",
      1: "apple",
      2: "cherry"}

for each in sorted(fruits.items(), key=lambda i:i[0]):
      print each[0], each[1]

BTW,sorted()返回一个两元素元组列表,而不是一个字典。

答案 4 :(得分:0)

正如文档所述,不,密钥不在Python字典中排序。但是很多人发现这种行为很有用,并且在PyPI上存在许多排序的dicts实现。 SortedDict数据类型与您观察到的完全相同:有效地按排序顺序维护其键。

一个这样的实现是sortedcontainers模块,它提供排序列表,排序的dict和排序的集合数据类型。它是在纯Python中实现的,但是是快速实现的。单元测试提供100%的覆盖率,并且通过了数小时的压力测试。

也许最重要的是,已排序的容器维护了performance comparison几个流行的实现,并描述了它们的权衡。