J'ai des données dans une liste de listes ou une liste de n-uplets, comme ceci:
data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]
Et je veux trier par le 2ème élément du sous-ensemble. Signification, trier par 2,5,8 où 2
provient de (1,2,3)
, 5
provient de (4,5,6)
. Quelle est la façon habituelle de faire cela? Devrais-je stocker des n-uplets ou des listes dans ma liste?
sorted_by_second = sorted(data, key=lambda tup: tup[1])
ou:
data.sort(key=lambda tup: tup[1]) # sorts in place
from operator import itemgetter
data.sort(key=itemgetter(1))
Je veux juste ajouter à la réponse de Stephen si vous voulez trier le tableau de haut en bas, une autre manière que dans les commentaires ci-dessus est simplement d'ajouter ceci à la ligne:
reverse = True
et le résultat sera le suivant:
data.sort(key=lambda tup: tup[1], reverse=True)
Pour le tri selon plusieurs critères, à savoir par exemple les deuxième et troisième éléments d’un tuple,
data = [(1,2,3),(1,2,1),(1,1,4)]
et ainsi définir un lambda qui retourne un tuple qui décrit la priorité, par exemple
sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]
la réponse de Stephen est celui que j'utiliserais. Pour être complet, voici le modèle DSU (decorate-sort-undecorate) avec liste des compréhensions:
decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]
Ou plus simplement:
[b for a,b in sorted((tup[1], tup) for tup in data)]
Comme indiqué dans le HowTo de Python , cela n’est plus nécessaire depuis Python 2.4, lorsque les fonctions de touche sont devenues disponibles.
Pour trier une liste de tuples (<Word>, <count>)
, pour count
dans l’ordre décroissant et Word
dans l’ordre alphabétique:
data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]
J'utilise cette méthode:
sorted(data, key=lambda tup:(-tup[1], tup[0]))
et ça me donne le résultat:
[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]
Sans lambda:
def sec_elem (s): renvoie s [1]
trié (données, clé = sec_elem)
La réponse de @Stephen va droit au but! Voici un exemple pour une meilleure visualisation,
Criez pour les fans de Ready Player One! =)
>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]
key
est une fonction appelée pour transformer les éléments de la collection à des fins de comparaison. Comme la méthode compareTo
en Java.
Le paramètre passé à key doit être un élément appelable. Ici, l'utilisation de lambda
crée une fonction anonyme (qui est appelable).
La syntaxe de lambda est le mot lambda suivi d’un nom itérable, puis d’un seul bloc de code.
Dans l'exemple ci-dessous, nous trions une liste de Tuple contenant les informations sur l'heure de certains événements et le nom de l'acteur.
Nous trions cette liste par heure d'occurrence d'événement - qui est le 0ème élément d'un tuple.
Remarque - s.sort([cmp[, key[, reverse]]])
trie les éléments de s en place
itemgetter()
est un peu plus rapide que lambda tup: tup[1]
, mais l'augmentation est relativement modeste (environ 10 à 25%).
(Session IPython)
>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [Tuple(values[i,:]) for i in range(len(values))]
>>> tpls[:5] # display sample from list
[(1, 0, 0),
(8, 5, 5),
(5, 4, 0),
(5, 7, 7),
(4, 2, 1)]
>>> sorted(tpls[:5], key=itemgetter(1)) # example sort
[(1, 0, 0),
(4, 2, 1),
(5, 4, 0),
(8, 5, 5),
(5, 7, 7)]
>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop
>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop
>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop
>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop