J'ai une liste de listes:
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
Si je voulais trier par un élément, disons l'élément haut / court, je pourrais le faire via s = sorted(s, key = itemgetter(1))
.
Si je voulais trier à la fois haut / court et couleur, je pourrais faire le tri deux fois, une fois pour chaque élément, mais existe-t-il un moyen plus rapide?
sort
. C'estsorted([(4, 2), (0, 3), (0, 1)]) == [(0, 1), (0, 3), (4, 2)]
.Réponses:
Une clé peut être une fonction qui renvoie un tuple:
Ou vous pouvez obtenir la même chose en utilisant
itemgetter
(ce qui est plus rapide et évite un appel de fonction Python):Et notez qu'ici, vous pouvez utiliser
sort
au lieu d'utilisersorted
puis de réaffecter:la source
-
de nombres entiers)revrse=True
uniquement,x[1]
est-ce possible?s = sorted(s, key = operator.itemgetter(2))
puis par le primaires = sorted(s, key = operator.itemgetter(1), reverse=True)
Pas idéal, mais ça marche.-1
.Je ne suis pas sûr que ce soit la méthode la plus pythonique ... J'avais une liste de tuples qui devaient être triés en premier par ordre décroissant des valeurs entières et ensuite par ordre alphabétique. Cela a nécessité d'inverser le tri entier mais pas le tri alphabétique. Voici ma solution: (à la volée dans un examen btw, je ne savais même pas que vous pouviez «imbriquer» des fonctions triées)
la source
b = sorted(a, key = lambda x: (-x[1], x[0]))
ce qui est le plus visible sur quels critères s'applique en premier. quant à l'efficacité, je ne suis pas sûr, quelqu'un doit le chronométrer.Plusieurs années de retard à la fête mais je souhaite à la fois trier sur 2 critères et utiliser
reverse=True
. Si quelqu'un d'autre veut savoir comment, vous pouvez mettre vos critères (fonctions) entre parenthèses:la source
Il semble que vous puissiez utiliser un
list
au lieu d'untuple
. Cela devient plus important, je pense, lorsque vous saisissez des attributs au lieu des «index magiques» d'une liste / tuple.Dans mon cas, je voulais trier par plusieurs attributs d'une classe, où les clés entrantes étaient des chaînes. J'avais besoin d'un tri différent à différents endroits et je voulais un tri par défaut commun pour la classe parent avec laquelle les clients interagissaient; avoir seulement à remplacer les «clés de tri» quand j'en avais vraiment «besoin», mais aussi de manière à pouvoir les stocker sous forme de listes que la classe pourrait partager
J'ai donc d'abord défini une méthode d'aide
puis l'utiliser
Cela utilisera la fonction lambda générée pour trier la liste
object.attrA
, puis enobject.attrB
supposant qu'elleobject
possède un getter correspondant aux noms de chaîne fournis. Et le deuxième cas trierait d'iciobject.attrC
làobject.attrA
.Cela vous permet également d'exposer potentiellement les choix de tri vers l'extérieur à partager de la même manière par un consommateur, un test unitaire, ou pour qu'ils vous disent peut-être comment ils veulent que le tri soit effectué pour une opération dans votre API en n'ayant qu'à vous donner une liste et non les coupler à votre implémentation back-end.
la source
Voici une façon: vous réécrivez essentiellement votre fonction de tri pour prendre une liste de fonctions de tri, chaque fonction de tri compare les attributs que vous souhaitez tester, à chaque test de tri, vous regardez et voyez si la fonction cmp renvoie un retour non nul si c'est le cas, rompez et envoyez la valeur de retour. Vous l'appelez en appelant un Lambda d'une fonction d'une liste de Lambdas.
Son avantage est qu'il ne traverse pas les données, pas une sorte de tri précédent comme le font d'autres méthodes. Une autre chose est qu'il trie sur place, alors que trié semble en faire une copie.
Je l'ai utilisé pour écrire une fonction de classement, qui classe une liste de classes où chaque objet est dans un groupe et a une fonction de score, mais vous pouvez ajouter n'importe quelle liste d'attributs. Notez l'utilisation non-lambda-like, mais hackish d'un lambda pour appeler un setter. La partie classement ne fonctionnera pas pour un tableau de listes, mais le tri fonctionnera.
Voici un moyen de classer une liste d'objets
la source