如何在Python中按键对字典进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4642501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 16:42:34  来源:igfitidea点击:

How to sort dictionaries by keys in Python

pythonsortingdictionary

提问by mgPePe

Can anyone tell me how I can sort this:

谁能告诉我如何排序:

{'a': [1, 2, 3], 'c': ['one', 'two'], 'b': ['blah', 'bhasdf', 'asdf'], 'd': ['asdf', 'wer', 'asdf', 'zxcv']}

into

进入

{'a': [1, 2, 3], 'b': ['blah', 'bhasdf', 'asdf'], 'c': ['one', 'two'],'d': ['asdf', 'wer', 'asdf', 'zxcv']}

? Thanks!

? 谢谢!

UPDATE 1, code sample:

更新 1,代码示例:

So I am doing linguistics. One article is broken down to words that are stored in a database and have all kinds of properties including para ID and sentence ID. The task: trying to rebuild the original text.

所以我在做语言学。一篇文章被分解为存储在数据库中的词,并具有各种属性,包括段落 ID 和句子 ID。任务:尝试重建原始文本。

Get 500 consecutive words from DB

从 DB 中获取 500 个连续单词

words = Words.objects.all()[wordId:wordId+500]
# I first create paragraphs, through which I can loop later in my django template,
# and in each para will be a list of words (also dictionaries). 
# So i am trying to get a dictionary with values that are lists of dictionaries. 
# 'pp' i make just for shorthanding a long-named variable.
paras={}
para_high = para_low =  words[0].belongs_to_paragraph
for w in words:
    last_word = w
    pp = w.belongs_to_paragraph
    if pp >para_high:
        para_high = pp
    if pp < para_low:
        para_low = pp
    if pp in paras:
        paras[pp].append(w)
    else:
        list = [w]
        paras[pp] = list
# Since there are blank lines between paragraphs, in rebuilding the text as it 
    #  looked originally, I need to insert blank lines. 
    # Since i have the ID's of the paragraphs and they go somewhat like that: 1,3,4,8,9 
    #(the gaps between 1 & 3 and 4 & 8 i have to fill in with something else, 
    # which is why i had para_low and para_high to loop the range. 
isbr = True
for i in range(para_low, para_high+1):
    if i in paras:
        isbr = True
    else:
        if isbr:
            paras[i]=['break']
            isbr = False
        else:
            paras[i]=[]

At this point, however, if I try to loop the dict and rebuild the text, some later id'd paragraphs come before previous ones, and that just doesn't do it.

然而,在这一点上,如果我尝试循环字典并重建文本,一些后来的 id'd 段落会出现在以前的段落之前,但这并没有做到。

UPDATE 2, loop code:

更新2,循环代码:

        {% for k,v in wording.iteritems()  %}
        {% if v[0] == 'break' %}
        <br/>
        {% else %}
        </div><div class="p">{% for word in v %}{% if word.special==0%} {% endif %}<span class="word {% if word.special == 0%}clickable{% endif%}" wid="{{word.id}}" special="{{word.special}}" somethingElse={{word.somethingElse}}>{{ word.word }}</span>{% endfor %}
        {% endif %}
    {% endfor %}

采纳答案by Mark Byers

Dicts don't have an order.

字典没有顺序。

You can call sorted but this just gives you a sorted list of the keys:

您可以调用 sorted ,但这只会为您提供一个排序的键列表:

>>> sorted(d)
['a', 'b', 'c', 'd']

You can treat it as an iterable and sort the key-value tuples, but then you've just got a list of tuples. That's not the same as a dict.

您可以将它视为一个可迭代对象并对键值元组进行排序,但这样您就得到了一个元组列表。这和 dict 不一样。

>>> sorted(d.items())
[
 ('a', [1, 2, 3]),
 ('b', ['blah', 'bhasdf', 'asdf']),
 ('c', ['one', 'two']),
 ('d', ['asdf', 'wer', 'asdf', 'zxcv'])
]

If you are using Python 2.7 or newer you could also consider using an OrderedDict.

如果您使用的是 Python 2.7 或更新版本,您还可以考虑使用OrderedDict.

dict subclass that remembers the order entries were added

添加了记住订单条目的 dict 子类

For example:

例如:

>>> d = collections.OrderedDict(sorted(d.items()))
>>> for k, v in d.items():
>>>     print k, v
a [1, 2, 3]
b ['blah', 'bhasdf', 'asdf']
c ['one', 'two']
d ['asdf', 'wer', 'asdf', 'zxcv']

回答by Nicholas Riley

As the other answer mentioned, the order of a dictionary's keys is arbitrary and you shouldn't rely on it.

正如另一个答案所提到的,字典键的顺序是任意的,你不应该依赖它。

If you're using Python 2.7 or 3.1 or later, try out collections.OrderedDict(2.7 docs; 3.1 docs; also see PEP 372). There's a link in the docs to a pure-Python version of OrderedDictthat works on earlier Python versions.

如果您使用的是 Python 2.7 或 3.1 或更高版本,请尝试collections.OrderedDict2.7 docs3.1 docs;另见PEP 372)。文档中有一个链接,指向适用于早期 Python 版本的 OrderedDictPython 版本。

回答by Lennart Regebro

The correctanswer is that if you want the items of a dictionary in a sorted order, you should use the sorted() function when you loop over the dictionary:

正确的回答是,如果你想在一个有序字典的项目,你应该使用排序()函数,当你遍历所有的字典

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

or

或者

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

Or similar.

或者类似的。

The OrderedDict mentioned is for dictionaries that have an order. And order is not the same as a sorting. You can create a sorted OrderedDict, yes, but as soon as you add a new key it is no longer sorted. So you would need to use sorted() anywayto sort it before each use or after each manipulation. The OrderedDict is therefore only slower and more memory intensive than an ordinary dictionary, while adding nothing you need.

提到的 OrderedDict 适用于有订单的字典。并且顺序与排序不同。您可以创建一个排序的 OrderedDict,是的,但是一旦您添加一个新键,它就不再排序。因此,您无论如何都需要使用 sorted()在每次使用之前或每次操作之后对其进行排序。因此,OrderedDict 仅比普通字典慢,占用更多内存,同时不添加任何您需要的内容。

OrderedDict are notfor sorted dictionaries, but for dictionaries where the items have some sort of ordering that is nota sorting. Such as if you want to show things in the order they were added, or if you want you users to be able to order things arbitrarily.

OrderedDict是不是对排序的词典,但对词典,其中的项目有一定的排序顺序的是不是一个排序。例如,如果您想按照添加的顺序显示内容,或者您​​希望用户能够任意排序内容。

Update: Further explanation

更新:进一步解释

Why is OrderedDict not a solution? Because an OrderedDict is orderednot sorted.

为什么 OrderedDict 不是解决方案?因为 OrderedDict 是有序的而不是排序的

Consider a standard dictionary:

考虑一个标准字典:

>>> d = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}

It's not sorted, as we see below, 'c' will come before 'b'. It also has no order, if we add new things it appears what seems like random order:

它没有排序,正如我们在下面看到的,'c' 将在 'b' 之前。它也没有顺序,如果我们添加新东西,它看起来像是随机顺序:

>>> d['g'] = 6
>>> d['i'] = 8
>>> d
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8}

OK, so let's use an OrderedDict then:

好的,那么让我们使用 OrderedDict :

>>> o = OrderedDict(sorted({'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}.items()))
>>> o
OrderedDict([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5)])

Aha! Sorted! So OrderedDict works!? No.

啊哈!排序!所以 OrderedDict 有效!?不。

>>> o['i'] = 8
>>> o['g'] = 6
>>> o
OrderedDict([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('i', 8), ('g', 6)])

What? The g ended up afterthe i?!? Why!? Because the OrderedDict is not sorted, it's ordered. It remembers the orderyou add things. Not the sorting. This means that every time you use it you need to sort it first. An OrderedDict will only stay sorted as long as you don't add keys to it. But if you aren't going to modify it, then you don't need a dict. You can just as well have a list. Which is what you get from sorted():

什么?g在 i之后结束了?!?为什么!?因为 OrderedDict 没有排序,所以它是有序的。它会记住您添加内容的顺序。不是排序。这意味着每次使用它时都需要先对其进行排序。只要您不向它添加键,OrderedDict 只会保持排序。但是,如果您不打算修改它,那么您就不需要 dict。你也可以有一个清单。这是你从 sorted() 得到的:

>>> sorted(o.items())
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('g', 6), ('i', 8)]

But that works just as well with the standard dictionary, so the OrderedDictionary didn't help:

但这与标准字典一样有效,因此 OrderedDictionary 没有帮助:

>>> sorted(d.items())
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('g', 6), ('i', 8)]

ConclusionSo each time you want to loop over the dictionary in a sorted way, you need to do:

结论所以每次你想以排序的方式遍历字典时,你需要这样做:

>>> for k in sorted(o):
...   print k, o[k]
... 
a 0
b 1
c 2
d 3
e 4
f 5
g 6
i 8

And that is no matter what dictionary you use. OrderedDict doesn't really help you, because it doesn't care about sorting, just the orderyou add things in.

这与您使用的词典无关。OrderedDict 并没有真正帮助你,因为它不关心排序,只关心你添加东西的顺序

回答by dave

It may also be worth mentioning the nlargest routine in heapq. This sorts and returns the top N items. Depending upon what is actually required, this may be handy if you play with the key parameter. I mainly mention this since I discovered it a couple of nights ago and it did exactly what I was after. See PEP 0265and Heapq.

可能还值得一提的是 heapq 中的 nlargest 例程。这将排序并返回前 N 个项目。根据实际需要,如果您使用 key 参数,这可能会很方便。我主要提到这一点,因为我几天前发现了它,它完全符合我的要求。参见PEP 0265Heapq

回答by kriss

I will add my one cent to what others already explained. I happened to have the exact same problem in one specific case. I needed the output of my dictionary to always be the same for writing stable unit-tests.

我将在其他人已经解释的内容上加上我的一分钱。在一个特定案例中,我碰巧遇到了完全相同的问题。为了编写稳定的单元测试,我需要字典的输出始终相同。

If by chance it is what you are trying to achieve, or some other output related task, you don't have to sort anything at all, just use pprintmodule, among other features it will sort dictionaries by keys.

如果碰巧这是您想要实现的目标,或其他一些与输出相关的任务,您根本不必对任何内容进行排序,只需使用pprint模块,除其他功能外,它还将按键对字典进行排序。

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

>>> from pprint import pprint
>>> pprint(d)
{'a': 1, 'b': 2, 'c': 3}

回答by GrantJ

It's worth noting that Python has a number of dictionary implementations that maintain the keys in sorted order. Consider the sortedcontainersmodule which is pure-Python and fast-as-C implementations. There's a performance comparisonwith other fast and feature-complete implementations benchmarked against one another.

值得注意的是,Python 有许多字典实现,它们按排序顺序维护键。考虑sortedcontainers模块,它是纯 Python 和 fast-as-C 实现。与其他以彼此为基准的快速且功能完整的实现进行性能比较

For example:

例如:

>>> from sortedcontainers import SortedDict
>>> d = {'a': [1, 2, 3], 'c': ['one', 'two'], 'b': ['blah', 'bhasdf', 'asdf'], 'd': ['asdf', 'wer', 'asdf', 'zxcv']}
>>> s = SortedDict(**d)
>>> s.keys()
SortedSet(['a', 'b', 'c', 'd'])

You can also entirely replace your use of dict with SortedDictas it supports fast get/set operations and sorted iterations of items by key.

您还可以将 dict 的使用完全替换为SortedDict,因为它支持快速获取/设置操作和按键对项目进行排序迭代。

回答by Cameron Landers

Here is a quick and easy function you can use to sort a dictionary by keys.

这是一个快速简单的函数,您可以使用它来按键对字典进行排序。

Put this code in a separate file called sdict.py:

将此代码放在名为 的单独文件中sdict.py

def sortdict(dct):
    kys = dct.keys()
    kys.sort()
    from collections import OrderedDict
    d = OrderedDict()
    for x in kys: 
        for k, v in dct.iteritems():
            if (k == x):
                d[k] = v
    return d

Now, place this code into a separate file called test.pyto test it with a sample dictionary:

现在,将此代码放入一个单独的文件中test.py,以使用示例字典对其进行测试:

from sdict import sortdict
import json
dct = {'sizes':[32,28,42], 'dog':'schnauser', 'cat':'siamese', 'bird':'falcon'}
dctx = sortdict(dct)
print json.dumps(dctx) 

And finally, call test.pyfrom the command line:

最后,test.py从命令行调用:

$ python test.py
{"bird": "falcon", "cat": "siamese", "dog": "schnauser", "sizes": [32, 28, 42]}

I'm only using json.dumps line to show you that it's an actual dictionary, and not just a string representation. You can also test it with the type() function for that matter.

我只是使用 json.dumps 行来向您展示它是一个实际的字典,而不仅仅是一个字符串表示。您还可以使用 type() 函数对此进行测试。

I included a nested list with numeric values in the sample dictionary to show that the function can handle more complex dictionaries, not just single-layer string-based dicts.

我在示例字典中包含了一个带有数值的嵌套列表,以表明该函数可以处理更复杂的字典,而不仅仅是基于单层字符串的字典。

The code is pretty straightforward, so it would be easy to modify it to sort by values, if that's your preference - although sorting by value would not make sense if some of the values are objects, like lists, tuples or other dicts.

代码非常简单,因此很容易修改它以按值排序,如果这是您的偏好 - 尽管如果某些值是对象,如列表、元组或其他字典,按值排序将没有意义。

Admittedly, this only works in python 2.7 or later.

诚然,这仅适用于 python 2.7 或更高版本。

Cheers,
-=Cameron

干杯,
-=卡梅隆