Python: ¿Cómo ordenar una lista de diccionarios por varios valores?

Quiero ordenar una lista al principio por un valor y luego por un segundo valor. ¿Hay una forma fácil de hacer esto? Aquí hay un pequeño ejemplo:

A = [{'name':'john','age':45}, {'name':'andi','age':23}, {'name':'john','age':22}, {'name':'paul','age':35}, {'name':'john','age':21}] 

Este comando es para ordenar esta lista por 'name' :

 sorted(A, key = lambda user: user['name']) 

Pero, ¿cómo puedo ordenar esta lista por un segundo valor? Como 'age' en este ejemplo.

Quiero una clasificación como esta (primero ordenar por 'name' y luego ordenar por 'age' ):

 andi - 23 john - 21 john - 22 john - 45 paul - 35 

¡Gracias!

 >>> A = [{'name':'john','age':45}, {'name':'andi','age':23}, {'name':'john','age':22}, {'name':'paul','age':35}, {'name':'john','age':21}] >>> sorted(A, key = lambda user: (user['name'], user['age'])) [{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}] 

Esto se ordena por una tupla de los dos atributos, lo siguiente es equivalente y mucho más rápido / más limpio:

 >>> from operator import itemgetter >>> sorted(A, key=itemgetter('name', 'age')) [{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}] 

De los comentarios: @Bakuriu

Apuesto a que no hay una gran diferencia entre los dos, pero el itemgetter evita un poco de sobrecarga porque extrae las claves y CALL_FUNCTION la tuple durante un solo código de operación ( CALL_FUNCTION ), mientras que al llamar a la lambda tendrá que llamar a la función, cargar los varios las constantes (que son otros BINARY_SUBSCR ) finalmente llaman al subíndice ( BINARY_SUBSCR ), construyen la tuple y la devuelven … eso es mucho más trabajo para el intérprete.

Para resumir: itemgetter mantiene la ejecución completamente en el nivel C , por lo que es lo más rápido posible.

 from operator import itemgetter sorted(your_list, key=itemgetter('name', 'age')) 

Aquí está la solución general alternativa: ordena los elementos de dictado por claves y valores. La ventaja es que no es necesario especificar las claves, y aún funcionaría si faltan algunas claves en algunos de los diccionarios.

 def sort_key_func(item): """ helper function used to sort list of dicts :param item: dict :return: sorted list of tuples (k, v) """ pairs = [] for k, v in item.items(): pairs.append((k, v)) return sorted(pairs)