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?

440
demandé sur codeforester 2010-06-26 03:01:41

10 réponses

sorted_by_second = sorted(data, key=lambda tup: tup[1])

ou:

data.sort(key=lambda tup: tup[1])  # sorts in place
797
répondu Stephen 2015-01-05 09:46:34
from operator import itemgetter
data.sort(key=itemgetter(1))
150
répondu manova 2013-11-11 08:18:15

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)
37
répondu sifoo 2017-03-06 23:20:54

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.

26
répondu tcarobruce 2017-05-23 11:47:29

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)]
23
répondu elm 2015-12-19 21:27:50

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)]
9
répondu l mingzhi 2017-02-15 05:35:22

sans lambda:

def sec_elem(s):
    return s[1] 
sorted(data, key=sec_elem) 
6
répondu Mesco 2018-01-02 15:16:51

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

5
répondu Rishi 2017-05-26 21:06:23

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
4
répondu Walter 2016-09-27 05:25:13

le tri d'un tuple est assez simple:

tuple(sorted(t))
-5
répondu Jayr 2014-12-30 22:28:21