2

I have a python dictionary:

d = {'a1': 123, 'a2': 2, 'a10': 333, 'a11': 4456}

When I sort the dictionary using OrderedDict I get the following output:

from collections import OrderedDict
OrderedDict(sorted(d.items()))
# Output
# OrderedDict([('a1', 123), ('a10', 333), ('a11', 4456), ('a2', 2)])

Is there a way to get it in the natural order:

OrderedDict([('a1', 123), ('a2', 2), ('a10', 333), ('a11', 4456)])
or 
{'a1': 123, 'a2': 2, 'a10': 333, 'a11': 4456}

Thanks.

cs95
  • 379,657
  • 97
  • 704
  • 746
Jeril
  • 7,858
  • 3
  • 52
  • 69

2 Answers2

9

You're in luck: The natsort module can help. First, install it using:

pip install natsort

Now, you can pass d.keys() to natsort.natsorted, and build a new OrderedDict.

import natsort
from collections import OrderedDict

d = {'a1' : 123, 
     'a2' : 2, 
     'a10': 333, 
     'a11': 4456}
keys = natsort.natsorted(d.keys())    
d_new = OrderedDict((k, d[k]) for k in keys)

A shorter version involves sorting d.items() (got this idea from RomanPerekhrest's answer):

d_new = OrderedDict(natsort.natsorted(d.items()))

d_new
OrderedDict([('a1', 123), ('a2', 2), ('a10', 333), ('a11', 4456)])
cs95
  • 379,657
  • 97
  • 704
  • 746
0

Short "trick" with chr() function on character code (no external packages):

import collections

d = {'a1': 123, 'a2': 2, 'a10': 333, 'a11': 4456}
result = collections.OrderedDict(sorted(d.items(), key=lambda x: chr(int(x[0][1:]))))
print(result)

The output:

OrderedDict([('a1', 123), ('a2', 2), ('a10', 333), ('a11', 4456)])
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105