Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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.

Get 500 consecutive words from DB

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.

UPDATE 2, loop code:

        {% 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 %} 
like image 462
mgPePe Avatar asked Jan 09 '11 23:01

mgPePe


People also ask

How do you sort a dictionary by key-value in Python?

To sort a dictionary by value in Python you can use the sorted() function. Python's sorted() function can be used to sort dictionaries by key, which allows for a custom sorting method. sorted() takes three arguments: object, key, and reverse. Dictionaries are unordered data structures.

Can we sort a dictionary with keys?

Dictionaries are made up of key: value pairs. Thus, they can be sorted by the keys or by the values.

How do I sort a list of dictionaries in a key in Python?

To sort a list of dictionaries according to the value of the specific key, specify the key parameter of the sort() method or the sorted() function. By specifying a function to be applied to each element of the list, it is sorted according to the result of that function.


2 Answers

Dicts don't have an order.

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

>>> 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.

>>> 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.

dict subclass that remembers the order entries were added

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'] 
like image 124
Mark Byers Avatar answered Sep 26 '22 06:09

Mark Byers


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:

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() anyway to 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 are not for sorted dictionaries, but for dictionaries where the items have some sort of ordering that is not a 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.

Update: Further explanation

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

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:

>>> 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:

>>> 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.

>>> 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?!? Why!? Because the OrderedDict is not sorted, it's ordered. 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. 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():

>>> 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:

>>> 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.

like image 38
Lennart Regebro Avatar answered Sep 25 '22 06:09

Lennart Regebro