简体   繁体   English

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

[英]In Python, how do I iterate over a dictionary in sorted key order?

There's an existing function that ends in the following, where d is a dictionary: 现有的函数以下结尾,其中d是字典:

return d.iteritems()

that returns an unsorted iterator for a given dictionary. 返回给定字典的未排序迭代器。 I would like to return an iterator that goes through the items sorted by key . 我想返回一个遍历按键排序的项目的迭代器。 How do I do that? 我怎么做?

Haven't tested this very extensively, but works in Python 2.5.2. 没有对此进行过广泛的测试,但是在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)
>>>

If you are used to doing for key, value in d.iteritems(): ... instead of iterators, this will still work with the solution above 如果您习惯于for key, value in d.iteritems(): ...执行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)
>>>

With Python 3.x, use d.items() instead of d.iteritems() to return an iterator. 使用Python 3.x,使用d.items()而不是d.iteritems()来返回迭代器。

Use the sorted() function: 使用sorted()函数:

return sorted(dict.iteritems())

If you want an actual iterator over the sorted results, since sorted() returns a list, use: 如果你想要一个实际的迭代器而不是排序的结果,因为sorted()返回一个列表,使用:

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

A dict's keys are stored in a hashtable so that is their 'natural order', ie psuedo-random. 字典的密钥存储在哈希表中,因此它们是“自然顺序”,即伪随机。 Any other ordering is a concept of the consumer of the dict. 任何其他排序都是dict消费者的概念。

sorted() always returns a list, not a dict. sorted()总是返回一个列表,而不是一个dict。 If you pass it a dict.items() (which produces a list of tuples), it will return a list of tuples [(k1,v1), (k2,v2), ...] which can be used in a loop in a way very much like a dict, but it is not in anyway a 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)]

The following feels like a dict in a loop, but it's not, it's a list of tuples being unpacked into k,v: 以下感觉就像一个循环中的字典,但事实并非如此,它是一个被解包为k,v的元组列表:

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

Roughly equivalent to: 大致相当于:

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

Greg's answer is right. 格雷格的回答是对的。 Note that in Python 3.0 you'll have to do 请注意,在Python 3.0中,您将不得不这样做

sorted(dict.items())

as iteritems will be gone. 因为iteritems将会消失。

You can now use OrderedDict in Python 2.7 as well: 您现在也可以在Python 2.7中使用OrderedDict

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

Here you have the what's new page for 2.7 version and the OrderedDict API . 这里有2.7版本和OrderedDict API 的新页面。

In general, one may sort a dict like so: 一般来说,人们可能会像这样排序一个字典:

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

For the specific case in the question, having a "drop in replacement" for d.iteritems(), add a function like: 对于问题中的特定情况,对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]

and so the ending line changes from 所以结束行改变了

return dict.iteritems()

to

return sortdict(dict)

or 要么

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)

This method still has an O(N log N) sort, however, after a short linear heapify, it yields the items in sorted order as it goes, making it theoretically more efficient when you do not always need the whole list. 此方法仍然具有O(N log N)排序,但是,在短线性堆化之后,它会按照排序顺序生成项目,从而在理论上当您不总是需要整个列表时更有效。

sorted returns a list, hence your error when you try to iterate over it, but because you can't order a dict you will have to deal with a list. sorted返回一个列表,因此当你尝试迭代它时你的错误,但因为你不能订购一个字典,你将不得不处理一个列表。

I have no idea what the larger context of your code is, but you could try adding an iterator to the resulting list. 我不知道你的代码的更大的上下文是什么,但你可以尝试在结果列表中添加一个迭代器。 like this maybe?: 这样吗?:

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

of course you will be getting back tuples now because sorted turned your dict into a list of tuples 当然,你现在会回到元组因为排序把你的字母变成了一个元组列表

ex: say your dict was: {'a':1,'c':3,'b':2} sorted turns it into a list: 例如:说你的字典是: {'a':1,'c':3,'b':2}排序将其转换为列表:

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

so when you actually iterate over the list you get back (in this example) a tuple composed of a string and an integer, but at least you will be able to iterate over it. 所以当你实际迭代列表时,你会得到一个由字符串和整数组成的元组(在这个例子中),但至少你可以迭代它。

If you want to sort by the order that items were inserted instead of of the order of the keys, you should have a look to Python's collections.OrderedDict . 如果要按插入项而不是键的顺序排序,则应该查看Python的collections.OrderedDict (Python 3 only) (仅限Python 3)

Assuming you are using CPython 2.x and have a large dictionary mydict, then using sorted(mydict) is going to be slow because sorted builds a sorted list of the keys of mydict. 假设你正在使用CPython 2.x并且有一个大字典mydict,那么使用sorted(mydict)将会很慢,因为sorted会构建一个mydict键的排序列表。

In that case you might want to look at my ordereddict package which includes a C implementation of sorteddict in C. Especially if you have to go over the sorted list of keys multiple times at different stages (ie. number of elements) of the dictionaries lifetime. 在这种情况下,您可能希望查看我的ordereddict包,其中包含C语言中的sorteddict的C实现。特别是如果您必须在字典生命周期的不同阶段(即元素数量)多次查看键的排序列表。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM