1

I have a python dictionary whose keys have the following pattern

<some x number of digits/alphabets> <some y number of alphabets><some z number of digits>

I want to sort the dictionary based on this keys. For e.g

01IB0610, 01IB062, 01IB064

should be 01IB062, 01IB064 01IB0610

Complete example is something like this:

{ '01IB0610' : {'a' : [] , 'b': [] }, '01IB062' : {'a' : [] , 'b': [] } , '01IB064' : {'a' : [] , 'b': [] }

Final Output should be:{ '01IB062' : {'a' : [] , 'b': [] }, '01IB064' : {'a' : [] , 'b': [] } , '01IB0610' : {'a' : [] , 'b': [] }

gizgok
  • 7,303
  • 21
  • 79
  • 124
  • The non-digit characters are always uppercase? – jscs Jul 26 '13 at 18:22
  • possible duplicate of [Does Python have a built in function for string natural sort?](http://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort) – Ashwini Chaudhary Jul 26 '13 at 18:22
  • 2
    a dictionary is an unordered set of key: value pairs, you cant sort it – Yoriz Jul 26 '13 at 18:23
  • possible duplicate of [Sorting alphanumerical dictionary keys in python](http://stackoverflow.com/questions/4253785/sorting-alphanumerical-dictionary-keys-in-python) – jscs Jul 26 '13 at 18:24
  • 1
    01IB062 comes before 01IB0604? is that a typo or is it before because it is shorter – vik Jul 26 '13 at 18:26

2 Answers2

3
import re

def key_func(s):
    return [int(x) if x.isdigit() else x for x in re.findall(r'\D+|\d+', s)]

sorted_keys = sorted(d, key=key_func)

Example:

>>> d = {'01IB0610': 'foo', '01IB062': 'bar', '01IB0604': 'baz'}
>>> sorted(d, key=key_func)
['01IB062', '01IB0604', '01IB0610']
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • you should explicitly say that a new list is returned - unlike list.sort() it does not use dict and some how give it ordering. – Eiyrioü von Kauyf Jul 26 '13 at 18:51
  • I did not add the fact that is dict of dict. The key is of the first dict though – gizgok Jul 26 '13 at 19:09
  • @gizgok Please give a complete example with your current dictionary and the end result you are hoping to get. – Andrew Clark Jul 26 '13 at 20:01
  • @F.J I added an example – gizgok Jul 26 '13 at 21:20
  • Dictionaries in Python cannot be sorted. You can use `collections.OrderedDict` which can keep the keys in a specific order, or you can just sort the keys as in my answer and then use that result to access the dictionary values according to that order. – Andrew Clark Jul 26 '13 at 21:37
0

I'm not sure I totally get the sorting criteria, but you can use an OrderedDict to have a dict that keeps particular order.

from collections import OrderedDict
import re
d = {'01IB0610': 1, '01IB062': 2, '01IB064': 3}

def criteria(x):
    number = int(re.sub('[^0-9]', '', x[0]) )
    length = len(x[0])
    return length, number
d = OrderedDict( sorted( d.items(), key = criteria ) )
d.keys()
>> ['01IB062', '01IB064', '01IB0610']

This creates an OrderedDict where the order of the elements in the original dict is based on a hierarchical sort of the keys of those elements. The first criteria is the length of the key, ie 01IB0610 comes after 01IB064 because its longer. The second criteria is based on the digits in the key, ie 01062 is before 01064.

qwwqwwq
  • 6,999
  • 2
  • 26
  • 49