Comment trier (liste/tuple) des listes/tuples?
j'ai des données dans une liste de listes ou d'une liste de tuples, 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 2e élément du sous-ensemble. Sens, le tri par 2,5,8 où 2 est de (1,2,3), 5 (4,5,6). Quelle est la façon habituelle de faire cela? Dois-je stocker des tuples ou des listes dans ma liste?
10 réponses
sorted_by_second = sorted(data, key=lambda tup: tup[1])
ou:
data.sort(key=lambda tup: tup[1]) # sorts in place
je veux juste ajouter à la réponse de Stephen si vous voulez trier le tableau de haut en bas, une autre façon autre que dans les commentaires ci-dessus est juste pour ajouter ceci à la ligne:
reverse = True
et le résultat sera le suivant:
data.sort(key=lambda tup: tup[1], reverse=True)
la réponse de Stephen est celle que j'utiliserais. Pour être complet, voici le modèle DSU (decorate-sort-undecorate) avec les compréhensions de liste:
decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]
ou, plus tersiquement:
[b for a,b in sorted((tup[1], tup) for tup in data)]
comme noté dans le Python Triing HowTo , cela n'a pas été nécessaire depuis Python 2.4, lorsque les fonctions clés sont devenues disponibles.
pour le tri par des critères multiples, à savoir par exemple par les deuxième et troisième éléments dans un tuple, let
data = [(1,2,3),(1,2,1),(1,1,4)]
et ainsi définir un lambda qui renvoie 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)]
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 il 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): return s[1]
sorted(data, key=sec_elem)
la réponse de @Stephen est pertinente! Voici un exemple pour une meilleure visualisation,
criez pour le joueur prêt un fans! =)
>>> 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 qui sera appelée pour transformer les articles de la collection pour la comparaison.. comme la méthode compareTo
en Java.
le paramètre passé à key doit être quelque chose qui est 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.
exemple ci-dessous, nous sommes en train de trier une liste de tuples qui contient l'heure INFO abt de certains événements et noms d'acteurs.
nous sommes en train de trier cette liste par heure d'occurrence de l'événement - qui est le 0ème élément d'un tuple.
Note - s.sort([cmp[, key[, reverse]]])
trie les articles de s en place
itemgetter()
est un peu plus rapide que lambda tup: tup[1]
, mais l'augmentation est relativement modeste (autour de 10 à 25 pour cent).
(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