Clasificación personalizada de Python Dictionary

Así que tengo un diccionario que se ve así cuando lo imprimo:

{'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} 

Quiero ordenar estos de manera personalizada, que defino. Digamos que la forma en que quiero que se ZT21 (por clave) es ZT21 , 10 , WX21 , UM , 5 , 2 .

¿Alguien sabe cómo resolver un diccionario de una manera predefinida / personalizada? Lo que estoy haciendo es obtener este diccionario de una base de datos, y puede salir con más de 20 claves, todas las cuales tienen un orden específico. El orden siempre se establece, pero a veces ciertas claves / valores no están en el diccionario. Así que esto también podría suceder:

 {'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} 

ordenado (por clave) es ZT21 , 10 , WX21 , UM , 5 , 2 .

Entonces, el 10 no está en este ejemplo, pero la clasificación que necesito sigue siendo la misma, el 10 estaría ausente.

¿Algunas ideas?

Los diccionarios en Python están desordenados. Puede obtener los resultados que necesita en forma de list

 >>> d = {'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} >>> keyorder = ['ZT21', '10', 'WX21', 'UM', '5', '2'] >>> sorted(d.items(), key=lambda i:keyorder.index(i[0])) [('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)] 

o como un OrderedDict

 >>> from collections import OrderedDict >>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.index(i[0]))) OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]) 

Si está haciendo muchos de estos, será más eficiente usar un dict para el orden de las llaves.

 >>> keyorder = {k:v for v,k in enumerate(['ZT21', '10', 'WX21', 'UM', '5', '2'])} >>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.get(i[0]))) OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]) 

Usted no puede Use un collections.OrderedDict lugar.

Los diccionarios están intrínsecamente desordenados, por lo que no puede ordenar directamente el diccionario. Puede ordenar los pares clave / valor ordenando someDict.items() y pasando una función clave como lo haría al ordenar cualquier otra cosa, pero obtendrá una lista ordenada y no un diccionario. Consulte las preguntas anteriores sobre clasificación de diccionarios: Python: clasificación de un diccionario de listas y clasificación de diccionarios por longitud de clave, por ejemplo.

Puede ordenarlo utilizando OrderedDict y especificando su pedido personalizado.

 def customsort(dict1 , key_order): items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] sorted_dict = OrderedDict() for i in range(len(key_order)): sorted_dict[key_order[i]] = items[i] return sorted_dict key_order = [ "monday" ,"tuesday" ,"wednesday" ,"thursday" ,"friday" ,"saturday"] dict1 ={"monday" : 10 , "thursday" :12 , "wednesday" : 34} sorted_dicti = customsort(dict1,key_order) print(sorted_dicti) 

Customsort () ordena el diccionario dado (dict1) por orden (key_order) pasado por el usuario.

 items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 

Verificará si la clave dada está en dict1; si está allí, entonces ponga el valor especificado en dict1;

 OrderedDict([('monday', 10), ('tuesday', 0), ('wednesday', 34), ('thursday', 12), ('friday', 0), ('saturday', 0)]) 

Tuve exactamente el mismo problema e ideé una solución general liviana:

 from collections import OrderedDict def make_custom_sort(orders): orders = [{k: -i for (i, k) in enumerate(reversed(order), 1)} for order in orders] def process(stuff): if isinstance(stuff, dict): l = [(k, process(v)) for (k, v) in stuff.items()] keys = set(stuff) for order in orders: if keys.issuperset(order): return OrderedDict(sorted(l, key=lambda x: order.get(x[0], 0))) return OrderedDict(sorted(l)) if isinstance(stuff, list): return [process(x) for x in stuff] return stuff return process 

Primero, creas una instancia de una función de ordenación personalizada:

 custom_sort = make_custom_sort([ ['ZT21', '10', 'WX21', 'UM', '5', '2'] ]) 

Ahora, la clasificación real:

 result = custom_sort(my_dataset) 

Las claves que faltan se rechazan al final en un orden no especificado. Tenga en cuenta que este cierre es recursivo. Como lo indican los corchetes dobles, puede especificar tantos ordenamientos como lo requieran los diversos diccionarios nesteds en su estructura.

Proyecto en GitHub: https://github.com/laowantong/customsort