Sorting dict items by key, beyond alphanumeric sorting

寵の児 提交于 2019-12-02 04:48:39

dicts are unordered, so to get the order you are going to have to sort the items and use an OrderedDict to maintain the sorted order. To get the order you want you can create tuples from the groups of integers so you sort as integers in lexicographical order:

from itertools import groupby
from collections import OrderedDict
d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0,
     'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0}

def key_func(x):
    """'a0p12' -> (0, 12)"""
    return tuple(int("".join(v)) for k,v in groupby(x[0], key=str.isdigit) if k)
od = OrderedDict(sorted(d.items(), key=key_func))

print(od)

Which would give you:

OrderedDict([('a0p12', 0), ('a1p11', 0), ('a2p10', 0), ('a3p9', 0), 
('a4p8', 0), ('a5p7', 0), ('a6p6', 0), ('a7p5', 0), ('a8p4', 0), 
('a9p3', 0), ('a10p2', 0), ('a11p1', 0), ('a12p0', 0)])

You could also use a regex to find the groups of digits:

from collections import OrderedDict
import re

d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0,
     'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0}



def key_func(x,patt=re.compile("\d+")):
    """'a0p12' -> (0, 12)"""
    return tuple(map(int, patt.findall(x[0])))

od = OrderedDict(sorted(d.items(), key=key_func))

print(od)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!