Aller au contenu

Tri des données⚓︎

Trier les données avec Python

Pour pouvoir exploiter plus facilement les données, il est souvent utile de les trier. Nous allons utiliser les fonctions prédéfinies par Python. Pour trier une liste, les deux possibilités sont liste.sort() qui modifie la liste pour que les éléments soient dans l'ordre croissant, et sorted(liste) qui renvoie une nouvelle liste triée.

Exemples d'utilisation
>>> liste = [7, 9, 1, 8]
>>> liste.sort()
>>> liste
[1, 7, 8, 9]
>>> liste = [7, 9, 1, 8]
>>> sorted(liste)
[1, 7, 8, 9]
>>> liste
[7, 9, 1, 8]
Trier des données complexes

Pour une liste de dictionnaires, il faut absolument donner la clef selon laquelle les données doivent être triées. Le paramètre donné pour l'argmuent key doit être une fonction qui prend n'importe quel élément de la liste et renvoie une valeur. Les éléments seront classés par rapport au résultat de cette fonction. Nous allns utiliser la syntaxe lambda x: f(x) qui veut dire qu'on associe à x la valeur f(x).

Exemples d'utilisation
>>> d = [{'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'},
...      {'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'},
...      {'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'}]
>>> sorted(d, key=lambda p: p["Nom"]) # tri par rapport au nom
[{'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'},
 {'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'},
 {'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'}]
>>> sorted(d, key=lambda p: p["Age"]) # par rapport à l'age
[{'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'},
 {'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'},
 {'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'}]
>>> sorted(d, key=lambda p: p["Sexe"]) # par rapport au sexe
[{'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'},
 {'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'},
 {'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'}]
>>> sorted(d, key=lambda p: (p["Sexe"], p["Age"])) # (sexe, age)
[{'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'},
 {'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'},
 {'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'}]

Dans le dernier exemple, vous pouvez remarquer qu'il est possible de donner un \(n\)-uplet pour définir plusieurs clefs de tri. En priorité, on trie par rapport à la première clef et en cas d'égalité, on regarde la suivante, et ainsi de suite. Cela permet d'affiner les tris de façons plus précises.

Enfin, il est possible de trier dans l'ordre décroissant en rajoutant le paramètre reverse=True :

Exemple d'utilisation
>>> sorted(d, key=lambda p: p["Age"], reverse=True)
[{'Nom': 'Bob', 'Age': 56, 'Sexe': 'H'}, 
 {'Nom': 'Lidia', 'Age': 35, 'Sexe': 'F'}, 
 {'Nom': 'Hachim', 'Age': 26, 'Sexe': 'H'}]

Pour tous les exercices, nous utiliserons sorted pour renvoyer un nouveau pokédex et ne pas modifier l'original. Puisque nous avons déjà défini des fonctions qui renvoient le nom, l'attaque ou le nombre de HP d'un pokémon, il est possible de les utiliser à la place de lambda :

Code à copier dans votre fichier
def tri_par_nom(pokedex):
    return sorted(pokedex, key=nom)
Exemple d'utilisation
>>> tri_par_nom(pokedex)
[OrderedDict([('Nom', 'Abo'), ('HP', 35), ...]), 
 OrderedDict([('Nom', 'Abra'), ('HP', 25), ...]), 
 OrderedDict([('Nom', 'Absol'), ('HP', 65), ...]), 
 OrderedDict([('Nom', 'Aflamanoir'), ('HP', 85), ...]),
 ...
Exercice 9

Écrire une fonction tri_par_attaque qui prend en paramètre une liste de dictionnaires pokedex et qui renvoie un nouveau pokédex avec les pokémons classés par l'ordre décroissant de leur niveau d'attaque. Le premier est celui qui a la plus forte attaque et le dernier est celui qui a la plus faible.

Exercice 10

Écrire une fonction tri_par_attaque_defense_vie qui prend en paramètre une liste de dictionnaires pokedex et qui renvoie un nouveau pokédex avec les pokémons classés par l'ordre décroissant de leur niveau d'attaque, de défense et de vie. Vous pourrez soit faire une fonction lambda ou alors définir une nouvelle fonction qui renvoit le triplet (a, d, v) composé de l'attaque, la défense et la vie du pokémon donné en paramètre.