Ordenar los elementos de dictado por clave, más allá de la ordenación alfanumérica

He escrito este código:

n=5 dizN={} for q in range(0,n+1): h=nq dizN['a'+str(q)+'p'+str(h)]=0 

que crea tal diccionario:

dizN

 Out[120]: {'a0p5': 0, 'a1p4': 0, 'a2p3': 0, 'a3p2': 0, 'a4p1': 0, 'a5p0': 0} 

Tenga en cuenta que “n” es el parámetro básico de mi código. Como puede ver, la sum de los enteros presentes en la cadena de claves dict es siempre = n (= 5 en este caso, donde n = 5).

Es importante para mí (para propósitos más difíciles en mi progtwig) que, para cada n que cualquiera pueda elegir, el dictado se ordene de esta manera:

 {'a0p(n)': 0, 'a1p(n-1)': 0, ....., 'a(n-1)p1': 0, 'a(n)p0': 0} 

Mi código está bien, pero solo para n = 10, esto es lo que sucede: (n = 12) dizN:

 Out[121]: {'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} 

Como puede ver, el intérprete sigue la ordenación alfanumérica;

Alguien sabe si hay una manera de obtener el mismo dictado ordenado de esta manera:

 {'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} 

?

Sé que los diccionarios son básicamente no clasificables, pero espero que alguien sepa algún truco para obtener mi propósito de todos modos 🙂

¡Muchas gracias!

Los dados no están ordenados , por lo que para obtener el orden, tendrá que ordenar los elementos y usar un OrderedDict para mantener el orden. Para obtener el orden que desea, puede crear tuplas a partir de grupos de enteros para que los clasifique como enteros en orden lexicográfico:

 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) 

Lo que te daría:

 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)]) 

También puede utilizar una expresión regular para encontrar los grupos de dígitos:

 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)