Order of Keys in Dictionary

Order of keys in dictionaries in old versions of Python

You could use OrderedDict (requires Python 2.7) or higher.

Also, note that OrderedDict({'a': 1, 'b':2, 'c':3}) won't work since the dict you create with {...} has already forgotten the order of the elements. Instead, you want to use OrderedDict([('a', 1), ('b', 2), ('c', 3)]).

As mentioned in the documentation, for versions lower than Python 2.7, you can use this recipe.

Order of keys in dictionary

Dictionaries are not ordered. So there is no way to do it.

If you have python2.7+, you can use collections.OrderedDict - in this case you could retrieve the item list using .items() and then reverse it and create a new OrderedDict from the reversed list:

>>> od = OrderedDict((('a', 'first'), ('b', 'second')))
>>> od
OrderedDict([('a', 'first'), ('b', 'second')])
>>> items = od.items() # list(od.items()) in Python3
>>> items.reverse()
>>> OrderedDict(items)
OrderedDict([('b', 'second'), ('a', 'first')])

If you are using an older python version you can get a backport from http://code.activestate.com/recipes/576693/

How do I sort a dictionary by key?

Note: for Python 3.7+, see this answer

Standard Python dictionaries are unordered (until Python 3.7). Even if you sorted the (key,value) pairs, you wouldn't be able to store them in a dict in a way that would preserve the ordering.

The easiest way is to use OrderedDict, which remembers the order in which the elements have been inserted:

In [1]: import collections

In [2]: d = {2:3, 1:89, 4:5, 3:0}

In [3]: od = collections.OrderedDict(sorted(d.items()))

In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])

Never mind the way od is printed out; it'll work as expected:

In [11]: od[1]
Out[11]: 89

In [12]: od[3]
Out[12]: 0

In [13]: for k, v in od.iteritems(): print k, v
....:
1 89
2 3
3 0
4 5

Python 3

For Python 3 users, one needs to use the .items() instead of .iteritems():

In [13]: for k, v in od.items(): print(k, v)
....:
1 89
2 3
3 0
4 5

How do I sort a dictionary by value?

Python 3.7+ or CPython 3.6

Dicts preserve insertion order in Python 3.7+. Same in CPython 3.6, but it's an implementation detail.

>>> x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> {k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

or

>>> dict(sorted(x.items(), key=lambda item: item[1]))
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

Older Python

It is not possible to sort a dictionary, only to get a representation of a dictionary that is sorted. Dictionaries are inherently orderless, but other types, such as lists and tuples, are not. So you need an ordered data type to represent sorted values, which will be a list—probably a list of tuples.

For instance,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x will be a list of tuples sorted by the second element in each tuple. dict(sorted_x) == x.

And for those wishing to sort on keys instead of values:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

In Python3 since unpacking is not allowed we can use

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])

If you want the output as a dict, you can use collections.OrderedDict:

import collections

sorted_dict = collections.OrderedDict(sorted_x)

How to change the order of keys in a Python 3.5 dictionary, using another list as a reference for keys?

Dicts are "officially" maintained in insertion order starting in 3.7. They were so ordered in 3.6, but it wasn't guaranteed before 3.7. Before 3.6, there is nothing you can do to affect the order in which keys appear.

But OrderedDict can be used instead. I don't understand your "but it gives me a list" objection - I can't see any sense in which that's actually true.

Your example:

>>> from collections import OrderedDict
>>> d = OrderedDict([('item', 'book'), ('pages', 200),
... ('weight', 1.0), ('price', 25),
... ('city', 'London')])
>>> d # keeps the insertion order
OrderedDict([('item', 'book'), ('pages', 200), ('weight', 1.0), ('price', 25), ('city', 'London')])
>>> key_order= ['city', 'pages', 'item', 'weight', 'price'] # the order you want
>>> for k in key_order: # a loop to force the order you want
... d.move_to_end(k)
>>> d # which works fine
OrderedDict([('city', 'London'), ('pages', 200), ('item', 'book'), ('weight', 1.0), ('price', 25)])

Don't be confused by the output format! d is displayed as a list of pairs, passed to an OrderedDict constructor, for clarity. d isn't itself a list.

What ordering does dict.keys() and dict.values() guarantee?

The general rules:

  1. Before talking about what is guaranteed and what isn't, even if some ordering seems to be "guaranteed", it isn't. You should not rely on it. It is considered bad practice, and could lead to nasty bugs.
  2. d.keys(), d.values(), and d.items() all return the elements in a respective order. The order should be treated as arbitrary (no assumptions should be made about it). (docs)
  3. consecutive calls to d.keys(), d.values(), and d.items() are "stable", in the sense they are guaranteed to preserve the order of previous calls (assuming no insertion/deletion happens between the calls).
  4. Since CPython's V3.6, dict has been reimplemented, and it now preserves insertion order. This was not the goal of the change, but a side effect, and it is NOT part of the python spec, only a detail of the CPython implementation. See point #1 above: relying on this is bad practice and should not be done. Anyways, you should avoid writing CPython-specific code.
  5. In Python2, order is deterministic (i.e. creating a dict twice in the same way will result with the same order). In Python <3.6, it is no longer deterministic, so you can't rely on that either (I'm not sure if this non-determinism is part of the spec or just a CPython implementation detail).

EDIT: added point #5, thanks to @AndyHayden's comment.

How can I get the keys in a dictionary in the order that they appear in the dictionary?

Try from this source: Key Order in Python Dictionaries

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

Sadly, OrderedDict({'a': 1, 'b':2, 'c':3}) won't work because The {} has already forgotten order of the elements.

Your code would be:

Dict = OrderedDict([('Name', 'Zara'), ('Age', 7), ('Class', 'First)])

Changing order of dictionaries keys based on preferred order

Suggested algorithm:

  1. Create a new, initially empty, dictionary;
  2. Iterate through preferred_order: for every key in preferred_order, add key: value to the new dictionary if it exists in the old dictionary, and remove it from the old dictionary;
  3. for every remaining key: value pair in the old dictionary, add it to the new dictionary.

For step 3, you can use dict.update or |=.

Further reading:

  • documentation on dict.update and |=;
  • more about |=;
  • How do I sort a dictionary by value?;
  • You can search for "sort dictionary by key" on stackoverflow, but be aware that most answers are outdated and recommend using collections.OrderedDict instead of dict, which is no longer necessary since Python 3.7.


Related Topics



Leave a reply



Submit