简体   繁体   English

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

[英]How to sort dictionaries by keys in Python

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. 一篇文章分解为存储在数据库中的单词,并具有各种属性,包括段ID和句子ID。 The task: trying to rebuild the original text. 任务:尝试重建原始文本。

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. 但是,在这一点上,如果我尝试循环dict并重建文本,一些后来的id段落在之前的段落之前,那就不会这样做。

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 %}

Dicts don't have an order. Dicts没有订单。

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']

The correct answer 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 : 正确答案是,如果您希望按排序顺序排列字典,则在循环字典时应使用sorted()函数:

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. 提到的OrderedDict适用于有订单的字典。 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. 您可以创建一个已排序的OrderedDict,但是,只要添加新密钥,就不再对其进行排序。 So you would need to use sorted() anyway to sort it before each use or after each manipulation. 所以你需要在每次使用之前或每次操作之后使用sorted()进行排序。 The OrderedDict is therefore only slower and more memory intensive than an ordinary dictionary, while adding nothing you need. 因此,OrderedDict只比普通字典更慢,占用内存更多,同时不需要添加任何内容。

OrderedDict are not for sorted dictionaries, but for dictionaries where the items have some sort of ordering that is not a sorting. OrderedDict 不适用于已排序的词典,但适用于字典,其中项目具有某种不是排序的排序。 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. 例如,如果您想按照添加的顺序显示内容,或者您​​希望用户能够任意订购内容。

Update: Further explanation 更新:进一步说明

Why is OrderedDict not a solution? 为什么OrderedDict不是解决方案? Because an OrderedDict is ordered not sorted . 因为订购的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'. 它没有排序,如下所示,'c'将在'b'之前出现。 It also has no order, if we add new things it appears what seems like random order: 它也没有订单,如果我们添加新的东西,它看起来像是随机顺序:

>>> 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!? 所以OrderedDict有效!? No. 没有。

>>> 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 after the i?!? 在我之后 ,g结束了吗?!? Why!? 为什么!? Because the OrderedDict is not sorted, it's ordered . 因为OrderedDict没有排序,所以它是有序的 It remembers the order you 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. 只要您不向其添加密钥,OrderedDict将仅保持排序。 But if you aren't going to modify it, then you don't need a dict. 但如果你不打算修改它,那么你就不需要dict了。 You can just as well have a list. 你也可以有一个清单。 Which is what you get from sorted(): 这是你从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)]

Conclusion So 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 order you add things in. OrderedDict并没有真正帮助你,因为它不关心排序 ,只关心你添加内容的顺序

It's worth noting that Python has a number of dictionary implementations that maintain the keys in sorted order. 值得注意的是,Python有许多字典实现,可以按排序顺序维护密钥。 Consider the sortedcontainers module which is pure-Python and fast-as-C implementations. 考虑sortedcontainers模块,它是纯Python和快速实现的C实现。 There's a performance comparison with other fast and feature-complete implementations benchmarked against one another. 与其他快速和功能完备的实现进行性能比较

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 SortedDict as it supports fast get/set operations and sorted iterations of items by key. 您还可以完全用SortedDict替换您对dict的使用,因为它支持快速获取/设置操作以及按键排序的项目迭代。

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 ). 如果你使用的是Python 2.7或3.1或更高版本,请试用collections.OrderedDict2.7 docs ; 3.1 docs ;另见PEP 372 )。 There's a link in the docs to a pure-Python version of OrderedDict that works on earlier Python versions. 文档中有一个链接到纯Python版的OrderedDict ,它适用于早期的Python版本。

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.py to 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.py from 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. 我只使用json.dumps行来向您显示它是一个真正的字典,而不仅仅是字符串表示。 You can also test it with the type() function for that matter. 您也可以使用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. 代码非常简单,因此很容易修改它以按值排序,如果这是您的偏好 - 尽管如果某些值是对象(如列表,元组或其他dicts),按值排序是没有意义的。

Admittedly, this only works in python 2.7 or later. 不可否认,这只适用于python 2.7或更高版本。

Cheers, 干杯,
-=Cameron - =卡梅伦

It may also be worth mentioning the nlargest routine in heapq. 也许值得一提的是heapq中的最大例程。 This sorts and returns the top N items. 这将排序并返回前N个项目。 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 0265 and Heapq . PEP 0265Heapq

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 pprint module, 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}

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

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