sumar - Ordene el diccionario anidado por valor y el resto por otro valor, en Python
recorrer un diccionario en python (4)
Mi otra respuesta fue incorrecta (como la mayoría de las respuestas aquí)
sorted_keys = sorted((key for key in outer_dict if outer_dict[key][''downloads'']),
key=lambda x: (outer_dict[key][''downloads''],
outer_dict[key][''downloads''])
reverse=True)
sorted_keys += sorted((key for key in outer_dict if not outer_dict[key][''downloads'']),
key=lambda x: outer_dict[key][''date''])
Esto creará una lista con los elementos que se han descargado ordenados en orden descendente en la parte frontal y el resto de los elementos que no se han descargado ordenados por fecha después de los que se han descargado.
Pero en realidad, la última parte de la respuesta de Eli Courtwrights es la mejor.
Considere este formato de diccionario.
{''KEY1'':{''name'':''google'',''date'':20100701,''downloads'':0},
''KEY2'':{''name'':''chrome'',''date'':20071010,''downloads'':0},
''KEY3'':{''name'':''python'',''date'':20100710,''downloads'':100}}
Me gustaría que el diccionario se clasificara por descargas primero, y luego todos los elementos sin descargas ordenados por fecha. Obviamente, un diccionario no se puede ordenar, solo necesito una lista ordenada de claves que puedo repetir.
[''KEY3'',''KEY1'',''KEY2'']
Ya puedo ordenar la lista por cualquier valor usando sorted
, pero ¿cómo puedo ordenar por segundo valor también?
Puede pasar una función de key
a sorted
que devuelve una tupla que contiene las dos cosas que desea clasificar. Suponiendo que su gran diccionario se llama d
:
def keyfunc(tup):
key, d = tup
return d["downloads"], d["date"]
items = sorted(d.items(), key = keyfunc)
Si lo prefiere, puede hacer esto con un lambda
, pero probablemente sea más claro. Aquí está el código equivalente basado en lambda:
items = sorted(d.items(), key = lambda tup: (tup[1]["downloads"], tup[1]["date"]))
Incidentalmente, ya que mencionó que primero quería ordenar por "descargas", los dos ejemplos anteriores se ordenan de acuerdo con los recuentos de descargas en orden ascendente. Sin embargo, desde el contexto parece que es posible que desee clasificar en orden decreciente de descargas, en cuyo caso diría
return -d["downloads"], d["date"]
en su keyfunc
. Si desea algo como ordenar en orden ascendente para los números de descarga que no son cero, luego de tener todos los registros de descarga cero, podría decir algo como
return (-d["downloads"] or sys.maxint), d["date"]
Utilice el argumento key
para sorted()
. Le permite especificar una función que, dado el elemento real que se está ordenando, devuelve un valor que debería ser ordenado por. Si este valor es una tupla, entonces se ordena como tuplas ordenadas por el primer valor y luego por el segundo valor.
sorted(your_list, key=lambda x: (your_dict[x][''downloads''], your_dict[x][''date'']))
a = {''KEY1'':{''name'':''google'',''date'':20100701,''downloads'':0},
''KEY2'':{''name'':''chrome'',''date'':20071010,''downloads'':0},
''KEY3'':{''name'':''python'',''date'':20100710,''downloads'':100}}
z = a.items()
z.sort(key=lambda x: (x[1][''downloads''], x[1][''date'']))