Tri en Python : guide complet de sorted(), list.sort() et du tri personnalisé
Updated on
Trier des données est l’une des opérations les plus fondamentales en programmation, et pourtant le choix entre la fonction sorted() de Python et la méthode list.sort() déroute souvent les développeurs. Que vous classiez des notes d’étudiants, organisiez des prix de produits ou traitiez des listes de fichiers, comprendre les mécanismes de tri de Python fait gagner du temps et évite des bugs. Ce guide explore tous les aspects du tri en Python, des listes de nombres basiques aux comparaisons personnalisées complexes, avec des exemples pratiques que vous pouvez appliquer immédiatement.
sorted() vs list.sort() : la différence essentielle
Python propose deux mécanismes principaux de tri qui semblent similaires, mais se comportent de manière fondamentalement différente. La fonction sorted() crée et renvoie une nouvelle liste triée tout en laissant l’originale inchangée. La méthode list.sort() modifie la liste sur place et renvoie None.
# sorted() returns a new list
numbers = [3, 1, 4, 1, 5]
sorted_nums = sorted(numbers)
print(sorted_nums) # [1, 1, 3, 4, 5]
print(numbers) # [3, 1, 4, 1, 5] - original unchanged
# list.sort() modifies in place
numbers = [3, 1, 4, 1, 5]
result = numbers.sort()
print(numbers) # [1, 1, 3, 4, 5] - original modified
print(result) # NoneCette distinction compte pour l’efficacité mémoire et la préservation des données. Utilisez sorted() quand vous devez conserver la liste d’origine ou quand vous triez des séquences immuables comme les tuples. Utilisez list.sort() quand vous travaillez avec de grandes listes, où créer une copie consommerait trop de mémoire.
# sorted() works with any iterable
tuple_data = (42, 17, 93, 8)
sorted_list = sorted(tuple_data) # Returns [8, 17, 42, 93]
# list.sort() only works on lists
# tuple_data.sort() # AttributeError: 'tuple' object has no attribute 'sort'Tri de base : nombres, chaînes et types mixtes
Le comportement de tri par défaut de Python suit l’ordre “naturel”. Les nombres sont triés numériquement, les chaînes alphabétiquement, et les listes de types mixtes exigent une gestion explicite.
# Numeric sorting
integers = [42, -7, 0, 93, 15]
print(sorted(integers)) # [-7, 0, 15, 42, 93]
floats = [3.14, 2.71, 1.41, 9.81]
print(sorted(floats)) # [1.41, 2.71, 3.14, 9.81]
# String sorting (lexicographic order)
words = ['zebra', 'apple', 'mango', 'banana']
print(sorted(words)) # ['apple', 'banana', 'mango', 'zebra']
# Mixed types cause errors in Python 3
mixed = [3, 'apple', 1.5]
# sorted(mixed) # TypeError: '<' not supported between instancesPour des nombres stockés sous forme de chaînes qui doivent être triés numériquement plutôt qu’alphabétiquement, convertissez-les au moment du tri :
# String numbers sort alphabetically
string_nums = ['10', '2', '100', '21']
print(sorted(string_nums)) # ['10', '100', '2', '21']
# Convert to int for numeric sorting
print(sorted(string_nums, key=int)) # ['2', '10', '21', '100']Tri inverse avec reverse=True
sorted() et list.sort() acceptent tous deux un paramètre reverse qui inverse l’ordre de tri. Ce paramètre vaut False par défaut (ordre croissant).
scores = [88, 92, 75, 95, 82]
# Descending order using reverse=True
print(sorted(scores, reverse=True)) # [95, 92, 88, 82, 75]
# In-place descending sort
scores.sort(reverse=True)
print(scores) # [95, 92, 88, 82, 75]
# Reverse alphabetical order
names = ['Alice', 'David', 'Bob', 'Charlie']
print(sorted(names, reverse=True)) # ['David', 'Charlie', 'Bob', 'Alice']Le paramètre key : logique de tri personnalisée
Le paramètre key accepte une fonction qui transforme chaque élément avant comparaison. Cela permet de trier selon des attributs spécifiques, des valeurs calculées ou des critères complexes, sans modifier les données originales.
# Sort by string length
words = ['python', 'is', 'awesome', 'for', 'data']
print(sorted(words, key=len)) # ['is', 'for', 'data', 'python', 'awesome']
# Sort by absolute value
numbers = [-5, -2, 3, -8, 1]
print(sorted(numbers, key=abs)) # [1, -2, 3, -5, -8]
# Sort case-insensitive
names = ['alice', 'Bob', 'CHARLIE', 'david']
print(sorted(names, key=str.lower)) # ['alice', 'Bob', 'CHARLIE', 'david']Fonctions lambda pour un tri “inline”
Les fonctions lambda offrent une syntaxe concise pour des key simples. Elles sont idéales pour des transformations à usage unique, quand définir une fonction séparée serait verbeux.
# Sort tuples by second element
pairs = [(1, 'b'), (3, 'a'), (2, 'd'), (4, 'c')]
print(sorted(pairs, key=lambda x: x[1]))
# [(3, 'a'), (1, 'b'), (4, 'c'), (2, 'd')]
# Sort strings by last character
words = ['python', 'java', 'ruby', 'go']
print(sorted(words, key=lambda s: s[-1]))
# ['java', 'go', 'ruby', 'python']
# Sort by distance from target value
target = 50
values = [45, 62, 38, 55, 48]
print(sorted(values, key=lambda x: abs(x - target)))
# [48, 45, 55, 38, 62]Tri selon plusieurs critères
Quand le tri nécessite plusieurs priorités, renvoyez un tuple depuis la fonction key. Python compare les tuples élément par élément, ce qui fournit un tri multi-niveaux naturel.
# Sort students by grade (descending), then name (ascending)
students = [
('Alice', 85),
('Bob', 92),
('Charlie', 85),
('David', 92)
]
sorted_students = sorted(students, key=lambda x: (-x[1], x[0]))
print(sorted_students)
# [('Bob', 92), ('David', 92), ('Alice', 85), ('Charlie', 85)]
# Sort dates by year (descending), then month (ascending)
dates = ['2024-03', '2023-12', '2024-01', '2023-08']
print(sorted(dates, key=lambda d: (-int(d[:4]), int(d[5:]))))
# ['2024-01', '2024-03', '2023-08', '2023-12']operator.itemgetter et operator.attrgetter
Le module operator fournit des alternatives optimisées aux lambdas pour des motifs de tri courants. Ces fonctions s’exécutent plus vite que les lambdas et améliorent la lisibilité du code.
from operator import itemgetter, attrgetter
# Sort by specific dictionary keys
data = [
{'name': 'Alice', 'age': 30, 'score': 85},
{'name': 'Bob', 'age': 25, 'score': 92},
{'name': 'Charlie', 'age': 30, 'score': 78}
]
# Sort by age, then score
sorted_data = sorted(data, key=itemgetter('age', 'score'))
print([d['name'] for d in sorted_data]) # ['Bob', 'Charlie', 'Alice']
# Sort by tuple elements
records = [(1, 'b', 300), (2, 'a', 100), (1, 'a', 200)]
print(sorted(records, key=itemgetter(0, 1)))
# [(1, 'a', 200), (1, 'b', 300), (2, 'a', 100)]Pour les attributs d’objets, utilisez attrgetter :
from operator import attrgetter
class Employee:
def __init__(self, name, salary, department):
self.name = name
self.salary = salary
self.department = department
def __repr__(self):
return f'{self.name}({self.department}, ${self.salary})'
employees = [
Employee('Alice', 75000, 'Engineering'),
Employee('Bob', 65000, 'Marketing'),
Employee('Charlie', 75000, 'Engineering')
]
# Sort by department, then salary (descending)
sorted_emps = sorted(employees, key=attrgetter('department'))
print(sorted_emps)Tri des dictionnaires
Les dictionnaires eux-mêmes ne sont pas ordonnés (même si Python 3.7+ préserve l’ordre d’insertion), mais vous pouvez trier leurs clés, leurs valeurs ou leurs items.
# Sort dictionary by keys
data = {'zebra': 3, 'apple': 1, 'mango': 2}
sorted_keys = sorted(data.keys())
print(sorted_keys) # ['apple', 'mango', 'zebra']
# Create new dict with sorted keys
sorted_dict = {k: data[k] for k in sorted_keys}
print(sorted_dict) # {'apple': 1, 'mango': 2, 'zebra': 3}
# Sort by values
sorted_by_value = sorted(data.items(), key=lambda x: x[1])
print(sorted_by_value) # [('apple', 1), ('mango', 2), ('zebra', 3)]
# Convert back to dictionary
sorted_dict = dict(sorted_by_value)Pour des types de valeurs plus complexes :
# Sort dictionary by nested values
products = {
'laptop': {'price': 999, 'stock': 5},
'phone': {'price': 599, 'stock': 12},
'tablet': {'price': 399, 'stock': 8}
}
# Sort by price
by_price = sorted(products.items(), key=lambda x: x[1]['price'])
print([(name, info['price']) for name, info in by_price])
# [('tablet', 399), ('phone', 599), ('laptop', 999)]
# Sort by stock (descending)
by_stock = sorted(products.items(), key=lambda x: -x[1]['stock'])
print([(name, info['stock']) for name, info in by_stock])
# [('phone', 12), ('tablet', 8), ('laptop', 5)]Tri de listes de tuples
Les tuples se trient naturellement en comparant leurs éléments de gauche à droite. Vous pouvez personnaliser ce comportement via des fonctions key.
# Default tuple sorting (compares element by element)
tuples = [(1, 'z'), (2, 'a'), (1, 'a'), (2, 'z')]
print(sorted(tuples))
# [(1, 'a'), (1, 'z'), (2, 'a'), (2, 'z')]
# Sort by second element only
print(sorted(tuples, key=lambda x: x[1]))
# [(2, 'a'), (1, 'a'), (1, 'z'), (2, 'z')]
# Sort by sum of numeric elements
coord_distances = [(1, 2), (3, 1), (2, 2), (1, 3)]
print(sorted(coord_distances, key=sum))
# [(1, 2), (2, 2), (1, 3), (3, 1)]Tri de listes de dictionnaires
Trier des dictionnaires dans des listes nécessite de préciser quelle clé utiliser pour la comparaison.
people = [
{'name': 'Alice', 'age': 30, 'city': 'New York'},
{'name': 'Bob', 'age': 25, 'city': 'San Francisco'},
{'name': 'Charlie', 'age': 30, 'city': 'Austin'}
]
# Sort by age
by_age = sorted(people, key=lambda x: x['age'])
print([p['name'] for p in by_age]) # ['Bob', 'Alice', 'Charlie']
# Sort by age (descending), then name (ascending)
by_age_name = sorted(people, key=lambda x: (-x['age'], x['name']))
print([f"{p['name']} ({p['age']})" for p in by_age_name])
# ['Alice (30)', 'Charlie (30)', 'Bob (25)']
# Using itemgetter (more efficient)
from operator import itemgetter
by_city = sorted(people, key=itemgetter('city'))
print([p['city'] for p in by_city])
# ['Austin', 'New York', 'San Francisco']Tri de listes d’objets
Les classes personnalisées nécessitent des fonctions key qui extraient des attributs comparables.
class Product:
def __init__(self, name, price, rating):
self.name = name
self.price = price
self.rating = rating
def __repr__(self):
return f'{self.name}(${self.price}, {self.rating}★)'
products = [
Product('Laptop', 999, 4.5),
Product('Phone', 599, 4.8),
Product('Tablet', 399, 4.2),
Product('Monitor', 299, 4.7)
]
# Sort by price
by_price = sorted(products, key=lambda p: p.price)
print(by_price)
# Sort by rating (descending)
by_rating = sorted(products, key=lambda p: -p.rating)
print(by_rating)
# Sort by value score (rating / price * 100)
by_value = sorted(products, key=lambda p: (p.rating / p.price) * 100, reverse=True)
print(by_value)Alternativement, implémentez la méthode __lt__ (less than) pour définir le comportement de tri par défaut :
class Student:
def __init__(self, name, gpa):
self.name = name
self.gpa = gpa
def __lt__(self, other):
return self.gpa > other.gpa # Higher GPA comes first
def __repr__(self):
return f'{self.name}({self.gpa})'
students = [Student('Alice', 3.8), Student('Bob', 3.9), Student('Charlie', 3.7)]
print(sorted(students)) # [Bob(3.9), Alice(3.8), Charlie(3.7)]Tri de chaînes insensible à la casse
Les comparaisons de chaînes sont sensibles à la casse par défaut, ce qui fait que les lettres majuscules passent avant les minuscules. Utilisez str.lower() ou str.casefold() pour un tri insensible à la casse.
# Case-sensitive sorting (default)
words = ['apple', 'Banana', 'cherry', 'Date']
print(sorted(words)) # ['Banana', 'Date', 'apple', 'cherry']
# Case-insensitive sorting
print(sorted(words, key=str.lower)) # ['apple', 'Banana', 'cherry', 'Date']
# Using casefold for Unicode handling
international = ['café', 'CAFÉ', 'Apple', 'apple']
print(sorted(international, key=str.casefold))Garantie de stabilité et algorithme Timsort
Python utilise l’algorithme Timsort, qui garantit un tri stable. La stabilité signifie que les éléments ayant des clés égales conservent leur ordre relatif d’origine.
# Stable sort preserves original order for equal elements
data = [
('Alice', 85),
('Bob', 92),
('Charlie', 85), # Same score as Alice
('David', 92) # Same score as Bob
]
# Sort by score only - original order preserved for ties
by_score = sorted(data, key=lambda x: x[1])
print(by_score)
# [('Alice', 85), ('Charlie', 85), ('Bob', 92), ('David', 92)]
# Alice appears before Charlie (both 85) because she came firstCette stabilité permet le tri en plusieurs passes :
# Multi-pass sorting using stability
records = [
{'name': 'Alice', 'dept': 'HR', 'salary': 60000},
{'name': 'Bob', 'dept': 'IT', 'salary': 75000},
{'name': 'Charlie', 'dept': 'HR', 'salary': 65000},
{'name': 'David', 'dept': 'IT', 'salary': 70000}
]
# First sort by salary
records.sort(key=lambda x: x['salary'], reverse=True)
# Then sort by department (stable, so salary order preserved within dept)
records.sort(key=lambda x: x['dept'])
for r in records:
print(f"{r['dept']}: {r['name']} (${r['salary']})")
# HR: Charlie ($65000)
# HR: Alice ($60000)
# IT: Bob ($75000)
# IT: David ($70000)Comparaison de performances : méthodes de tri
Le tri en Python a une complexité temporelle O(n log n) dans le pire des cas, ce qui le rend efficace pour la plupart des datasets. Différentes approches conviennent à différents scénarios :
| Method | Time Complexity | Space | Use Case |
|---|---|---|---|
list.sort() | O(n log n) | O(1) | In-place sorting, large lists |
sorted() | O(n log n) | O(n) | Preserve original, sort any iterable |
heapq.nsmallest(k, items) | O(n log k) | O(k) | Top k elements from large dataset |
heapq.nlargest(k, items) | O(n log k) | O(k) | Bottom k elements from large dataset |
bisect.insort(list, item) | O(n) | O(1) | Maintain sorted list with insertions |
import heapq
# When you only need top 3 scores from 1 million records
scores = list(range(1000000))
top_3 = heapq.nlargest(3, scores) # Much faster than sorted()[-3:]
print(top_3) # [999999, 999998, 999997]
# When you need bottom 5 values
bottom_5 = heapq.nsmallest(5, scores)
print(bottom_5) # [0, 1, 2, 3, 4]Pour maintenir une liste triée avec des insertions fréquentes :
import bisect
# Maintain sorted list efficiently
sorted_list = []
for value in [5, 2, 8, 1, 9, 3]:
bisect.insort(sorted_list, value)
print(sorted_list) # [1, 2, 3, 5, 8, 9]functools.cmp_to_key pour les fonctions de comparaison héritées
Python 2 utilisait des fonctions de comparaison renvoyant -1, 0 ou 1. Python 3 exige des fonctions key, mais functools.cmp_to_key convertit les anciennes fonctions de comparaison.
from functools import cmp_to_key
# Custom comparison: sort by remainder when divided by 3
def compare_mod3(x, y):
return (x % 3) - (y % 3)
numbers = [10, 11, 12, 13, 14, 15]
sorted_nums = sorted(numbers, key=cmp_to_key(compare_mod3))
print(sorted_nums) # [12, 15, 10, 13, 11, 14]
# Groups: [12,15] (mod 0), [10,13] (mod 1), [11,14] (mod 2)
# Complex comparison: version strings
def compare_versions(v1, v2):
parts1 = list(map(int, v1.split('.')))
parts2 = list(map(int, v2.split('.')))
for p1, p2 in zip(parts1, parts2):
if p1 != p2:
return p1 - p2
return len(parts1) - len(parts2)
versions = ['1.10.2', '1.9.0', '1.10.15', '2.0.0', '1.10']
sorted_versions = sorted(versions, key=cmp_to_key(compare_versions))
print(sorted_versions) # ['1.9.0', '1.10', '1.10.2', '1.10.15', '2.0.0']Tri avec des valeurs None
Les valeurs None provoquent des erreurs de comparaison lorsqu’elles sont mélangées avec d’autres types. Gérez-les explicitement en les plaçant au début ou à la fin.
# None values cause errors
data = [3, None, 1, 5, None, 2]
# sorted(data) # TypeError: '<' not supported between 'NoneType' and 'int'
# Place None values at the end
sorted_data = sorted(data, key=lambda x: (x is None, x))
print(sorted_data) # [1, 2, 3, 5, None, None]
# Place None values at the beginning
sorted_data = sorted(data, key=lambda x: (x is not None, x))
print(sorted_data) # [None, None, 1, 2, 3, 5]
# Replace None with specific value for sorting
sorted_data = sorted(data, key=lambda x: x if x is not None else float('-inf'))
print(sorted_data) # [None, None, 1, 2, 3, 5]Pour des dictionnaires avec des clés potentiellement manquantes :
records = [
{'name': 'Alice', 'score': 85},
{'name': 'Bob'}, # Missing score
{'name': 'Charlie', 'score': 92},
{'name': 'David'} # Missing score
]
# Sort with default value for missing keys
sorted_records = sorted(records, key=lambda x: x.get('score', 0))
print([r['name'] for r in sorted_records])
# ['Bob', 'David', 'Alice', 'Charlie']Exemple concret : classement des performances des étudiants
Cet exemple montre plusieurs techniques de tri combinées pour construire un système de classement complet :
class StudentRecord:
def __init__(self, name, test_scores, attendance, extra_credit=0):
self.name = name
self.test_scores = test_scores
self.attendance = attendance
self.extra_credit = extra_credit
@property
def average_score(self):
return sum(self.test_scores) / len(self.test_scores) if self.test_scores else 0
@property
def final_grade(self):
base = self.average_score * 0.8 + self.attendance * 0.2
return min(100, base + self.extra_credit)
def __repr__(self):
return f'{self.name}: {self.final_grade:.1f}'
students = [
StudentRecord('Alice', [85, 90, 88], 95, 5),
StudentRecord('Bob', [92, 88, 95], 80, 0),
StudentRecord('Charlie', [78, 82, 80], 100, 10),
StudentRecord('David', [90, 92, 88], 90, 2),
StudentRecord('Eve', [85, 85, 85], 95, 0)
]
# Rank by final grade (highest first), then name
rankings = sorted(students, key=lambda s: (-s.final_grade, s.name))
print("Student Rankings:")
for rank, student in enumerate(rankings, 1):
print(f"{rank}. {student}")Exemple concret : traitement de listes de fichiers
Trier des métadonnées de fichiers nécessite de gérer différents types de données et une logique d’ordre personnalisée :
import os
from datetime import datetime
class FileInfo:
def __init__(self, path):
self.name = os.path.basename(path)
self.path = path
self.size = os.path.getsize(path)
self.modified = os.path.getmtime(path)
self.extension = os.path.splitext(path)[1].lower()
def __repr__(self):
size_kb = self.size / 1024
mod_time = datetime.fromtimestamp(self.modified).strftime('%Y-%m-%d %H:%M')
return f'{self.name} ({size_kb:.1f} KB, {mod_time})'
# Simulate file information
files = [
FileInfo('/data/report.pdf'),
FileInfo('/data/summary.txt'),
FileInfo('/data/analysis.xlsx'),
FileInfo('/data/backup.pdf'),
]
# Sort by extension, then size (largest first)
by_type_size = sorted(files, key=lambda f: (f.extension, -f.size))
# Sort by modification time (most recent first)
by_recent = sorted(files, key=lambda f: -f.modified)
# Sort by size, handling different units
def format_size(bytes_size):
if bytes_size < 1024:
return f"{bytes_size} B"
elif bytes_size < 1024 * 1024:
return f"{bytes_size/1024:.1f} KB"
else:
return f"{bytes_size/(1024*1024):.1f} MB"
by_size = sorted(files, key=lambda f: f.size, reverse=True)
for f in by_size:
print(f"{f.name}: {format_size(f.size)}")Tri interactif des données avec PyGWalker
Quand vous travaillez avec de grands datasets qui nécessitent une exploration visuelle et un tri interactif, PyGWalker transforme des DataFrames pandas en interfaces de type Tableau. Au lieu d’écrire une logique de tri complexe, vous pouvez glisser-déposer des colonnes pour trier, filtrer et analyser les données visuellement :
import pandas as pd
import pygwalker as pyg
# Create sample sales data
sales_data = pd.DataFrame({
'product': ['Laptop', 'Phone', 'Tablet', 'Monitor', 'Keyboard'] * 100,
'region': ['North', 'South', 'East', 'West', 'Central'] * 100,
'revenue': [999, 599, 399, 299, 49] * 100,
'units_sold': [50, 120, 80, 95, 200] * 100,
'date': pd.date_range('2024-01-01', periods=500)
})
# Launch interactive visualization
pyg.walk(sales_data)PyGWalker permet :
- Le tri multi-colonnes avec un retour visuel
- Le filtrage dynamique combiné au tri
- Le tri par champs calculés sans écrire de code
- L’export de vues triées sous forme de graphiques ou de tableaux
Cette approche fonctionne particulièrement bien pour explorer des datasets inconnus ou présenter des résultats à des parties prenantes non techniques qui doivent comprendre des tendances sans exécuter de code Python.
FAQ
Quelle est la différence entre sorted() et list.sort() en Python ?
La fonction sorted() renvoie une nouvelle liste triée et fonctionne avec n’importe quel itérable, en laissant l’original inchangé. La méthode list.sort() modifie la liste sur place, renvoie None et ne fonctionne qu’avec des objets de type list. Utilisez sorted() pour préserver les données d’origine ou trier des séquences non-list comme les tuples ; utilisez list.sort() pour l’efficacité mémoire lors du tri de grandes listes.
Comment trier une liste en ordre décroissant en Python ?
Ajoutez le paramètre reverse=True à sorted() ou list.sort(). Par exemple : sorted([3, 1, 4], reverse=True) renvoie [4, 3, 1]. Cela fonctionne avec tout type de données ayant un ordre naturel, y compris les nombres, les chaînes et les dates.
Peut-on trier un dictionnaire par valeur en Python ?
Les dictionnaires n’ont pas d’ordre “traditionnel”, mais vous pouvez trier leurs items par valeur avec sorted() et une fonction key : sorted(dict.items(), key=lambda x: x[1]). Cela renvoie une liste de tuples triée par valeur. Convertissez en dictionnaire avec dict(sorted(...)) si besoin, en gardant à l’esprit que l’ordre n’est préservé qu’à partir de Python 3.7+.
Comment trier une liste de dictionnaires selon une clé spécifique ?
Utilisez sorted() avec une lambda qui extrait la clé : sorted(list_of_dicts, key=lambda x: x['keyname']). Pour de meilleures performances, utilisez operator.itemgetter : sorted(list_of_dicts, key=itemgetter('keyname')). Les deux approches fonctionnent pour trier selon une ou plusieurs clés.
Quelle est la complexité temporelle du tri en Python ?
sorted() et list.sort() utilisent Timsort, avec une complexité O(n log n) dans le pire des cas et O(n) dans le meilleur des cas pour des données partiellement triées. La complexité mémoire est O(n) pour sorted() (création d’une nouvelle liste) et O(1) pour list.sort() (sur place). Pour extraire les k meilleurs éléments d’un grand dataset, heapq.nlargest() offre une complexité O(n log k).
Comment gérer les valeurs None lors d’un tri ?
Les valeurs None entraînent des erreurs de comparaison lorsqu’elles sont mélangées avec d’autres types. Utilisez une fonction key qui les place au début ou à la fin : sorted(data, key=lambda x: (x is None, x)) place None à la fin, tandis que sorted(data, key=lambda x: (x is not None, x)) les place au début. Pour des dictionnaires avec des clés manquantes, utilisez x.get('key', default_value) pour fournir une valeur par défaut.
Le tri en Python est-il stable ?
Oui. Le tri de Python est garanti stable : les éléments ayant des clés égales conservent leur ordre relatif d’origine. Cela permet un tri en plusieurs passes (trier selon un critère puis un autre) en conservant le premier tri en cas d’égalité. Cette stabilité est assurée par Timsort.
Conclusion
Les capacités de tri de Python offrent des outils puissants pour organiser efficacement les données. La distinction entre sorted() et list.sort() aide à prendre des décisions adaptées à la mémoire, tandis que le paramètre key et les fonctions lambda permettent une logique de tri personnalisée et sophistiquée. Comprendre le tri stable, l’ordre multi-critères et les caractéristiques de performance vous permet de choisir la meilleure approche selon le scénario.
Que vous classiez les performances d’étudiants, traitiez des métadonnées de fichiers ou analysiez des indicateurs métier, ces techniques de tri constituent la base des workflows de manipulation de données. Pour l’exploration visuelle et le tri interactif, PyGWalker étend ces capacités via des interfaces glisser-déposer qui complètent le tri programmatique.
Maîtrisez ces schémas de tri pour écrire un code plus propre, améliorer les performances et gérer en toute confiance des besoins complexes d’organisation des données.