Ou, en pratique, comment puis-je trier une liste de dictionnaires par plusieurs touches?
J'ai une liste de dictés:
b = [{u'TOT_PTS_Misc': u'Utley, Alex', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Russo, Brandon', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Chappell, Justin', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Foster, Toney', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Lawson, Roman', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Lempke, Sam', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Gnezda, Alex', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Kirks, Damien', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Worden, Tom', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Korecz, Mike', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Swartz, Brian', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Burgess, Randy', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Smugala, Ryan', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Harmon, Gary', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Blasinsky, Scott', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Carter III, Laymon', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Coleman, Johnathan', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Venditti, Nick', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Blackwell, Devon', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Kovach, Alex', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Bolden, Antonio', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Smith, Ryan', u'Total_Points': 60.0}]
et je dois utiliser un tri multi-clé inversé par Total_Points, puis non inversé par TOT_PTS_Misc
.
Cela peut être fait à l'invite de commande comme ceci:
a = sorted(b, key=lambda d: (-d['Total_Points'], d['TOT_PTS_Misc']))
Mais je dois exécuter cela via une fonction, où je passe dans la liste et les clés de tri. Par exemple def multikeysort(dict_list, sortkeys):
,.
Comment la ligne lambda peut-elle être utilisée pour trier la liste, pour un nombre arbitraire de clés qui sont passées à la fonction multikeysort, et prendre en compte que les clés de tri peuvent avoir n'importe quel nombre de clés et que celles qui nécessitent des tris inversés seront identifiées avec un '-' avant?
cmp()
n'est pas disponible pour Python3, j'ai donc dû le définir moi-même, comme mentionné ici: stackoverflow.com/a/22490617/398514cmp
mot - clé, mais lacmp()
fonction est toujours utilisée 4 lignes ci-dessus. Je l'ai essayé avec 3.2, 3.3, 3.4 et 3.5, ils ont tous échoué à l'appel de fonction, car ilcmp()
n'est pas défini. La troisième puce ici ( docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons ) mentionne le traitementcmp()
comme disparu.Cet article présente un bon aperçu des différentes techniques pour ce faire. Si vos exigences sont plus simples que le "multikey bidirectionnel complet", jetez un œil. Il est clair que la réponse acceptée et le billet de blog que je viens de citer se sont influencés d'une certaine manière, même si je ne sais pas dans quel ordre.
Au cas où le lien meurt, voici un résumé très rapide des exemples non couverts ci-dessus:
la source
result = cmp(fn(left), fn(right))
Je sais que c'est une question assez ancienne, mais aucune des réponses ne mentionne que Python garantit un ordre de tri stable pour ses routines de tri telles que
list.sort()
etsorted()
, ce qui signifie que les éléments qui se comparent égaux conservent leur ordre d'origine.Cela signifie que l'équivalent de
ORDER BY name ASC, age DESC
(en utilisant la notation SQL) pour une liste de dictionnaires peut être fait comme ceci:Notez comment les éléments sont d'abord triés par l'attribut "moindre"
age
(décroissant), puis par l'attribut "majeur"name
, conduisant à l'ordre final correct.L'inversion / inversion fonctionne pour tous les types pouvant être commandés, pas seulement pour les nombres que vous pouvez annuler en mettant un signe moins devant.
Et en raison de l'algorithme de Timsort utilisé dans (au moins) CPython, c'est en fait plutôt rapide dans la pratique.
la source
la source
some_string.split(",")
J'utilise ce qui suit pour trier un tableau 2d sur un certain nombre de colonnes
Cela pourrait être étendu pour fonctionner sur un nombre arbitraire d'éléments. J'ai tendance à penser qu'il vaut mieux trouver un meilleur modèle d'accès à vos clés triables que d'écrire un comparateur sophistiqué.
la source
J'ai eu un problème similaire aujourd'hui - je devais trier les éléments du dictionnaire par valeurs numériques décroissantes et par valeurs de chaîne ascendantes. Pour résoudre le problème des directions contradictoires, j'ai annulé les valeurs entières.
Voici une variante de ma solution - applicable à OP
Très simple - et fonctionne comme un charme
la source
Manifestation:
L'analyse est un peu fragile, mais au moins elle permet un nombre variable d'espaces entre les clés.
la source
Puisque vous êtes déjà à l'aise avec lambda, voici une solution moins verbeuse.
la source