J'ai la liste suivante créée à partir d'un csv trié
list1 = sorted(csv1, key=operator.itemgetter(1))
Je voudrais en fait trier la liste selon deux critères: d'abord par la valeur dans le champ 1 et ensuite par la valeur dans le champ 2. Comment faire?
__lt__()
méthode sur votre classe ou hériter d'une classe qui le fait" ? Cela en ferait un bien meilleur canonique.Réponses:
comme ça:
la source
operator
est un module qui doit être importé.Pas besoin d'importer quoi que ce soit lors de l'utilisation des fonctions lambda.
Les éléments suivants sont triés
list
par le premier élément, puis par le deuxième élément.la source
-
in-x[1]
?Python a un tri stable, donc à condition que les performances ne soient pas un problème, le moyen le plus simple est de le trier par champ 2, puis de le trier à nouveau par champ 1.
Cela vous donnera le résultat que vous voulez, le seul hic, c'est que s'il s'agit d'une grande liste (ou si vous voulez la trier souvent), appeler tri deux fois peut être une surcharge inacceptable.
En procédant de cette manière, il est également facile de gérer la situation dans laquelle vous souhaitez que certaines des colonnes soient triées de manière inversée, incluez simplement le paramètre 'reverse = True' si nécessaire.
Sinon, vous pouvez transmettre plusieurs paramètres à itemgetter ou créer manuellement un tuple. Cela va probablement être plus rapide, mais a le problème que cela ne se généralise pas bien si certaines des colonnes veulent être triées par inversion (les colonnes numériques peuvent toujours être inversées en les annulant, mais cela empêche le tri d'être stable).
Donc, si vous n'avez pas besoin de colonnes triées inversement, optez pour plusieurs arguments dans itemgetter, si vous le pouvez, et les colonnes ne sont pas numériques ou si vous voulez garder le tri stable pour plusieurs tris consécutifs.
Edit: Pour les commentateurs qui ont du mal à comprendre comment cela répond à la question d'origine, voici un exemple qui montre exactement comment la nature stable du tri garantit que nous pouvons faire des tris séparés sur chaque clé et finir avec des données triées sur plusieurs critères:
Ceci est un exemple exécutable, mais pour sauver les personnes qui l'exécutent, le résultat est:
Notez en particulier comment dans la deuxième étape le
reverse=True
paramètre maintient les prénoms dans l'ordre alors que le simple tri puis l'inversion de la liste perdraient l'ordre souhaité pour la troisième clé de tri.la source
la source
tuple()
pouvoir recevoir deux arguments (ou plutôt trois, si vous comptez avecself
)return
déclaration devrait êtrereturn tuple((x[1], x[2]))
ou simplementreturn x[1], x[2]
. Référez- vous à la réponse @jaap ci-dessous si vous recherchez un tri dans différentes directionstuple(x[1:3])
, si vous souhaitez utiliser le constructeur de tuple pour une raison quelconque au lieu d'une simple liste d'affichage de tuplex[1], x[2]
. Oukeyfunc = operator.itemgetter(1, 2)
et n'écrivez même pas une fonction vous-même.Nous pouvons également utiliser .sort avec lambda 2 fois car le tri python est en place et stable. Cela triera d'abord la liste en fonction du deuxième élément, x [1]. Ensuite, il triera le premier élément, x [0] (priorité la plus élevée).
Cela équivaut à faire ce qui suit: employés.sort (clé = lambda x: (x [0], x [1]))
la source
Par ordre croissant, vous pouvez utiliser:
ou dans l'ordre décroissant, vous pouvez utiliser:
la source
Le tri de la liste des dictionnaires ci-dessous triera la liste par ordre décroissant sur la première colonne comme salaire et la deuxième colonne comme âge
Résultat: [{'salaire': 123, 'âge': 25}, {'salaire': 123, 'âge': 23}]
la source