在Python中,如何按排序键顺序迭代字典?

时间:2008-12-12 23:57:05

标签: python sorting dictionary

现有的函数以下结尾,其中d是字典:

return d.iteritems()

返回给定字典的未排序迭代器。我想返回一个迭代器,它遍历按键排序的项目。我该怎么做?

10 个答案:

答案 0 :(得分:158)

没有对此进行过广泛的测试,但在Python 2.5.2中有效。

>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>

如果您习惯于使用for key, value in d.iteritems(): ...代替迭代器,那么这仍将适用于上述解决方案

>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>>     print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>

使用Python 3.x,使用d.items()而不是d.iteritems()来返回迭代器。

答案 1 :(得分:80)

使用sorted()功能:

return sorted(dict.iteritems())

如果您希望实际迭代器超过排序结果,因为sorted()返回列表,请使用:

return iter(sorted(dict.iteritems()))

答案 2 :(得分:38)

dict的密钥存储在哈希表中,因此它们是“自然顺序”,即伪随机。任何其他排序都是dict消费者的概念。

sorted()始终返回一个列表,而不是一个dict。如果你传递一个dict.items()(产生一个元组列表),它将返回一个元组列表[(k1,v1),(k2,v2),...]可以在循环中使用在某种程度上非常像一个字典,但它不是一个字典

foo = {
    'a':    1,
    'b':    2,
    'c':    3,
    }

print foo
>>> {'a': 1, 'c': 3, 'b': 2}

print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]

print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]

以下感觉就像一个循环中的字典,但事实并非如此,它是一个被解包为k的元组列表,v:

for k,v in sorted(foo.items()):
    print k, v

大致相当于:

for k in sorted(foo.keys()):
    print k, foo[k]

答案 3 :(得分:30)

格雷格的答案是对的。请注意,在Python 3.0中,您必须执行

sorted(dict.items())

iteritems将会消失。

答案 4 :(得分:6)

您现在也可以在Python 2.7中使用OrderedDict

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

这里有2.7版本的what's new页面和OrderedDict API

答案 5 :(得分:5)

一般来说,人们可能会像这样排序:

for k in sorted(d):
    print k, d[k]

对于问题中的特定情况,对d.iteritems()进行“替换”,添加如下函数:

def sortdict(d, **opts):
    # **opts so any currently supported sorted() options can be passed
    for k in sorted(d, **opts):
        yield k, d[k]

所以结束行从

改变
return dict.iteritems()

return sortdict(dict)

return sortdict(dict, reverse = True)

答案 6 :(得分:4)

>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
        keys = list(d)
        heapq.heapify(keys) # Transforms to heap in O(N) time
        while keys:
            k = heapq.heappop(keys) # takes O(log n) time
            yield (k, d[k])


>>> i = iter_sorted(d)
>>> for x in i:
        print x


('a', 4)
('b', 9)
('c', 2)
('d', 8)

此方法仍然具有O(N log N)排序,但是,在短线性堆化之后,它会按照排序顺序生成项目,从而在理论上当您不总是需要整个列表时更有效。

答案 7 :(得分:3)

sorted返回一个列表,因此当你尝试迭代它时你的错误, 但因为你不能订购一个字典,你将不得不处理一个清单。

我不知道代码的大背景是什么,但你可以尝试添加一个 结果列表的迭代器。 这样可能吗?:

return iter(sorted(dict.iteritems()))

当然你现在会回到元组因为排序把你的dict变成了一个元组列表

例如:  说你的命令是:  {'a':1,'c':3,'b':2} 已排序将其转换为列表:

[('a',1),('b',2),('c',3)]

所以当你实际迭代列表时,你会回来(在这个例子中)一个元组 由字符串和整数组成,但至少你可以迭代它。

答案 8 :(得分:3)

如果您想按插入项目的顺序而不是按键顺序排序,那么您应该查看Python的collections.OrderedDict。 (仅限Python 3)

答案 9 :(得分:2)

假设你正在使用CPython 2.x并且有一个大词典mydict,那么使用sorted(mydict)会变慢,因为sorted会构建一个mydict键的排序列表。

在这种情况下,您可能希望查看我的ordereddict包,其中包含C中sorteddict的C实现。特别是如果您必须在不同阶段多次检查已排序的键列表(即数字)字典中的元素)。

http://anthon.home.xs4all.nl/Python/ordereddict/