220

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

return d.iteritems()

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

4

10 回答 10

182

尚未对此进行非常广泛的测试,但可以在 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()返回迭代器。

于 2008-12-13T00:49:38.063 回答
83

使用sorted()功能:

return sorted(dict.iteritems())

如果您想要对排序结果进行实际迭代,因为sorted()返回一个列表,请使用:

return iter(sorted(dict.iteritems()))
于 2008-12-12T23:57:53.613 回答
41

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

sorted() 总是返回一个列表,而不是一个字典。如果你传递给它一个 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)]

以下感觉就像一个循环中的 dict,但它不是,它是一个元组列表被解压缩到 k,v 中:

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

大致相当于:

for k in sorted(foo.keys()):
    print k, foo[k]
于 2008-12-13T00:44:32.723 回答
33

格雷格的回答是对的。请注意,在 Python 3.0 中,您必须这样做

sorted(dict.items())

iteritems消失的。

于 2008-12-13T00:00:20.020 回答
7

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

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

在这里,您可以看到2.7 版本的新增功能页面和OrderedDict API

于 2013-07-08T17:49:52.737 回答
5

一般来说,可以像这样对 dict 进行排序:

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)
于 2013-03-06T20:53:01.927 回答
5
>>> 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) 排序,但是,在一个简短的线性 heapify 之后,它会按排序顺序生成项目,当你并不总是需要整个列表时,理论上它会更有效。

于 2013-04-11T04:39:35.657 回答
4

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

于 2011-12-09T10:25:31.380 回答
3

sorted 返回一个列表,因此当您尝试对其进行迭代时会出现错误,但是因为您无法订购 dict 您将不得不处理一个列表。

我不知道您的代码的更大上下文是什么,但您可以尝试将迭代器添加到结果列表中。也许像这样?:

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

当然,您现在将获得元组,因为 sorted 将您的 dict 变成了元组列表

例如:说你的 dict 是: {'a':1,'c':3,'b':2} sorted 把它变成一个列表:

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

因此,当您实际迭代列表时,您会返回(在此示例中)一个由字符串和整数组成的元组,但至少您将能够迭代它。

于 2008-12-13T01:27:02.513 回答
2

假设您使用的是 CPython 2.x 并且有一个大字典 mydict,那么使用 sorted(mydict) 会很慢,因为 sorted 会构建 mydict 键的排序列表。

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

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

于 2012-06-18T09:57:20.500 回答