在Python中,我如何迭代按sorting顺序的字典?
有一个现有的函数结束于:
return dict.iteritems()
返回给定字典的未sorting迭代器。 我想返回一个迭代器,通过按sorting顺序的项目。 我怎么做?
这非常广泛的testing,但是在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(): ...
来代替迭代器,则这仍然可以用上面的解决scheme
>>> d = {"x":2, "h":15, "a":2222} >>> for key, value in sorted(d.iteritems()): >>> print(key, value) ('a', 2222) ('h', 15) ('x', 2) >>>
使用sorted()
函数:
return sorted(dict.iteritems())
如果你想要一个实际的迭代器来sorting结果,因为sorted()
返回一个列表,所以使用:
return iter(sorted(dict.iteritems()))
字典的键存储在散列表中,所以这是他们的“自然顺序”,即伪随机。 任何其他顺序是字典的消费者的概念。
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)]
下面在循环中感觉像是一个字典,但它不是,这是一个被解压缩到k,v中的元组列表:
for k,v in sorted(foo.items()): print k, v
大致相当于:
for k in sorted(foo.keys()): print k, foo[k]
格雷格的回答是对的。 请注意,在Python 3.0中,你必须这样做
sorted(dict.items())
因为iteritems
将会消失。
你现在可以在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版本和OrderedDict API的新特性 。
一般来说,人们可以这样来sorting一个字典:
for k in sorted(d): print k, d[k]
对于问题中的具体情况,为d.iteritems()添加“drop in replace”,添加如下函数:
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)
>>> 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日志N)sorting,但是,在一个简短的线性heapify之后,它会按顺序产生sorting顺序的项目,从理论上讲,当您不需要整个列表时,效率会更高。
sorting返回一个列表,因此当你尝试遍历它时你的错误,但因为你不能命令字典,你将不得不处理一个列表。
我不知道你的代码的更大的上下文是什么,但你可以尝试添加一个迭代器到结果列表。 这样也许?:
return iter(sorted(dict.iteritems()))
当然,你现在将得到元组,因为sorting将你的字典转换为元组列表
例如:说你的字典是: {'a':1,'c':3,'b':2}
sorting成一个列表:
[('a',1),('b',2),('c',3)]
所以当你实际遍历列表时,你会得到一个由一个string和一个整数组成的元组,但是至less你可以迭代它。
如果你想按项目插入的顺序sorting,而不是键的顺序,你应该看看Python的collections.OrderedDict 。 (仅限Python 3)
假设你正在使用CPython 2.x并且有一个很大的字典mydict,那么使用sorted(mydict)的速度会很慢,因为sorting会build立一个有序的mydict键列表。
在这种情况下,您可能需要查看我的ordereddict包,其中包含C语言的C语言实现。特别是如果您必须在字典生命周期的不同阶段(即元素数量)多次遍历sorting的键列表。