Comment utiliser une fonction lambda pour le tri personnalisé en Python

PythonPythonBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Les fonctions lambda de Python offrent un moyen concis et puissant d'effectuer des opérations de tri personnalisées. Dans ce tutoriel, nous allons explorer comment utiliser les fonctions lambda pour trier des données en Python, ouvrant de nouvelles possibilités pour la manipulation et l'analyse des données. À la fin, vous aurez une solide compréhension de l'utilisation des fonctions lambda pour le tri personnalisé et serez capable d'appliquer ces techniques à vos propres projets Python.

Comprendre les fonctions Lambda

En Python, une fonction lambda est une petite fonction anonyme définie avec le mot-clé lambda. Contrairement aux fonctions régulières qui utilisent le mot-clé def, les fonctions lambda peuvent être créées en ligne et ne nécessitent pas de définition séparée.

Créons un nouveau fichier Python pour explorer les fonctions lambda. Ouvrez le WebIDE et créez un nouveau fichier appelé basic_lambda.py dans le répertoire /home/labex/project/lambda_sorting.

Ajoutez le code suivant à basic_lambda.py :

## Define a regular function
def square_function(x):
    return x * x

## The equivalent lambda function
square_lambda = lambda x: x * x

## Test both functions
number = 5
print(f"Using regular function: {number}² = {square_function(number)}")
print(f"Using lambda function: {number}² = {square_lambda(number)}")

## Lambda with multiple arguments
add = lambda x, y: x + y
print(f"{3} + {4} = {add(3, 4)}")

Exécutons maintenant ce fichier dans le terminal :

python3 basic_lambda.py

Vous devriez voir une sortie comme celle-ci :

Using regular function: 5² = 25
Using lambda function: 5² = 25
3 + 4 = 7

Les fonctions lambda sont particulièrement utiles lorsque vous avez besoin d'une fonction simple pour une courte période, notamment lors de l'utilisation de fonctions telles que map(), filter() ou sorted(). Créons un autre exemple pour voir les lambdas en action avec la fonction map().

Créez un nouveau fichier appelé lambda_with_map.py avec le contenu suivant :

## Using lambda with map() to apply a function to all items in a list
numbers = [1, 2, 3, 4, 5]

## Square all numbers using map with a lambda function
squared_numbers = list(map(lambda x: x * x, numbers))

print(f"Original numbers: {numbers}")
print(f"Squared numbers: {squared_numbers}")

## Double all numbers using map with a lambda function
doubled_numbers = list(map(lambda x: x * 2, numbers))
print(f"Doubled numbers: {doubled_numbers}")

Exécutez ce fichier :

python3 lambda_with_map.py

Vous devriez voir :

Original numbers: [1, 2, 3, 4, 5]
Squared numbers: [1, 4, 9, 16, 25]
Doubled numbers: [2, 4, 6, 8, 10]

Comprendre les fonctions lambda est essentiel avant de les appliquer au tri. Dans l'étape suivante, nous allons explorer comment utiliser les fonctions lambda avec les fonctions de tri de Python.

Tri de base avec les fonctions Lambda

Python propose deux méthodes principales pour trier les collections : la fonction sorted() et la méthode .sort() pour les listes. Nous pouvons utiliser les fonctions lambda avec les deux pour créer une logique de tri personnalisée.

Créons un nouveau fichier appelé basic_sorting.py pour explorer le tri de base avec les fonctions lambda :

## Basic sorting examples
fruits = ["apple", "banana", "cherry", "date", "elderberry", "fig"]

## Sort alphabetically (default behavior)
alphabetical = sorted(fruits)
print(f"Alphabetical order: {alphabetical}")

## Sort by length using a lambda function
by_length = sorted(fruits, key=lambda x: len(x))
print(f"Sorted by length: {by_length}")

## Sort by the last character
by_last_char = sorted(fruits, key=lambda x: x[-1])
print(f"Sorted by last character: {by_last_char}")

## Sort in reverse order (longest to shortest)
longest_first = sorted(fruits, key=lambda x: len(x), reverse=True)
print(f"Longest to shortest: {longest_first}")

Exécutez ce fichier :

python3 basic_sorting.py

Vous devriez voir une sortie comme :

Alphabetical order: ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig']
Sorted by length: ['fig', 'date', 'apple', 'cherry', 'banana', 'elderberry']
Sorted by last character: ['banana', 'apple', 'date', 'fig', 'cherry', 'elderberry']
Longest to shortest: ['elderberry', 'banana', 'cherry', 'apple', 'date', 'fig']

Le paramètre key dans sorted() prend une fonction qui transforme chaque élément avant la comparaison. Les fonctions lambda fournissent un moyen concis de créer ces transformations.

Essayons maintenant de trier avec des structures de données plus complexes. Créez un fichier appelé sorting_tuples.py :

## Sorting lists of tuples
students = [
    ("Alice", 21, 85),
    ("Bob", 19, 90),
    ("Charlie", 22, 78),
    ("David", 20, 92),
    ("Eve", 18, 88)
]

print("Original student data:")
for student in students:
    print(f"  {student[0]}: age {student[1]}, grade {student[2]}")

## Sort by name (first element in tuple)
by_name = sorted(students, key=lambda student: student[0])
print("\nSorted by name:")
for student in by_name:
    print(f"  {student[0]}: age {student[1]}, grade {student[2]}")

## Sort by age (second element)
by_age = sorted(students, key=lambda student: student[1])
print("\nSorted by age:")
for student in by_age:
    print(f"  {student[0]}: age {student[1]}, grade {student[2]}")

## Sort by grade (third element)
by_grade = sorted(students, key=lambda student: student[2], reverse=True)
print("\nSorted by grade (highest first):")
for student in by_grade:
    print(f"  {student[0]}: age {student[1]}, grade {student[2]}")

Exécutez ce fichier :

python3 sorting_tuples.py

Vous devriez voir les étudiants triés de différentes manières :

Original student data:
  Alice: age 21, grade 85
  Bob: age 19, grade 90
  Charlie: age 22, grade 78
  David: age 20, grade 92
  Eve: age 18, grade 88

Sorted by name:
  Alice: age 21, grade 85
  Bob: age 19, grade 90
  Charlie: age 22, grade 78
  David: age 20, grade 92
  Eve: age 18, grade 88

Sorted by age:
  Eve: age 18, grade 88
  Bob: age 19, grade 90
  David: age 20, grade 92
  Alice: age 21, grade 85
  Charlie: age 22, grade 78

Sorted by grade (highest first):
  David: age 20, grade 92
  Bob: age 19, grade 90
  Eve: age 18, grade 88
  Alice: age 21, grade 85
  Charlie: age 22, grade 78

Dans l'étape suivante, nous allons explorer des techniques de tri plus avancées en utilisant les fonctions lambda.

Techniques de tri avancées

Maintenant que nous comprenons les bases, explorons des techniques de tri plus avancées en utilisant les fonctions lambda.

Tri des dictionnaires

Les dictionnaires sont une structure de données courante en Python, et nous avons souvent besoin de trier des listes de dictionnaires. Créez un fichier appelé sorting_dictionaries.py :

## Sorting lists of dictionaries
products = [
    {"name": "Laptop", "price": 999.99, "stock": 25},
    {"name": "Phone", "price": 499.50, "stock": 42},
    {"name": "Tablet", "price": 299.75, "stock": 15},
    {"name": "Headphones", "price": 149.99, "stock": 34},
    {"name": "Mouse", "price": 24.99, "stock": 55}
]

## Print original products
print("Original product list:")
for product in products:
    print(f"  {product['name']}: ${product['price']}, Stock: {product['stock']}")

## Sort by price (lowest to highest)
by_price = sorted(products, key=lambda product: product["price"])
print("\nSorted by price (lowest to highest):")
for product in by_price:
    print(f"  {product['name']}: ${product['price']}, Stock: {product['stock']}")

## Sort by stock (highest to lowest)
by_stock = sorted(products, key=lambda product: product["stock"], reverse=True)
print("\nSorted by stock (highest to lowest):")
for product in by_stock:
    print(f"  {product['name']}: ${product['price']}, Stock: {product['stock']}")

## Sort by name (alphabetically)
by_name = sorted(products, key=lambda product: product["name"])
print("\nSorted by name:")
for product in by_name:
    print(f"  {product['name']}: ${product['price']}, Stock: {product['stock']}")

Exécutez ce fichier :

python3 sorting_dictionaries.py

Vous devriez voir les produits triés de différentes manières :

Original product list:
  Laptop: $999.99, Stock: 25
  Phone: $499.5, Stock: 42
  Tablet: $299.75, Stock: 15
  Headphones: $149.99, Stock: 34
  Mouse: $24.99, Stock: 55

Sorted by price (lowest to highest):
  Mouse: $24.99, Stock: 55
  Headphones: $149.99, Stock: 34
  Tablet: $299.75, Stock: 15
  Phone: $499.5, Stock: 42
  Laptop: $999.99, Stock: 25

Sorted by stock (highest to lowest):
  Mouse: $24.99, Stock: 55
  Phone: $499.5, Stock: 42
  Headphones: $149.99, Stock: 34
  Laptop: $999.99, Stock: 25
  Tablet: $299.75, Stock: 15

Sorted by name:
  Headphones: $149.99, Stock: 34
  Laptop: $999.99, Stock: 25
  Mouse: $24.99, Stock: 55
  Phone: $499.5, Stock: 42
  Tablet: $299.75, Stock: 15

Tri multi-niveaux

Parfois, nous devons trier des éléments en utilisant plusieurs critères. Par exemple, nous pourrions vouloir trier les étudiants d'abord par note, puis par âge pour ceux qui ont la même note.

Créez un fichier appelé multi_level_sorting.py :

## Multi-level sorting example
students = [
    {"name": "Alice", "grade": "A", "age": 21},
    {"name": "Bob", "grade": "B", "age": 19},
    {"name": "Charlie", "grade": "A", "age": 22},
    {"name": "David", "grade": "C", "age": 20},
    {"name": "Eve", "grade": "B", "age": 18},
    {"name": "Frank", "grade": "A", "age": 19}
]

print("Original student list:")
for student in students:
    print(f"  {student['name']}: Grade {student['grade']}, Age {student['age']}")

## Sort by grade (A to C), then by age (youngest to oldest)
## To sort by grade, we create a dictionary for grade priorities
grade_priority = {"A": 1, "B": 2, "C": 3}  ## A is highest priority (lowest number)

by_grade_then_age = sorted(students,
                           key=lambda student: (grade_priority[student["grade"]], student["age"]))

print("\nSorted by grade (A first), then by age (youngest first):")
for student in by_grade_then_age:
    print(f"  {student['name']}: Grade {student['grade']}, Age {student['age']}")

## Sort by age (oldest to youngest), then by name (alphabetically)
by_age_then_name = sorted(students,
                          key=lambda student: (-student["age"], student["name"]))

print("\nSorted by age (oldest first), then by name:")
for student in by_age_then_name:
    print(f"  {student['name']}: Grade {student['grade']}, Age {student['age']}")

Exécutez ce fichier :

python3 multi_level_sorting.py

Vous devriez voir :

Original student list:
  Alice: Grade A, Age 21
  Bob: Grade B, Age 19
  Charlie: Grade A, Age 22
  David: Grade C, Age 20
  Eve: Grade B, Age 18
  Frank: Grade A, Age 19

Sorted by grade (A first), then by age (youngest first):
  Frank: Grade A, Age 19
  Alice: Grade A, Age 21
  Charlie: Grade A, Age 22
  Eve: Grade B, Age 18
  Bob: Grade B, Age 19
  David: Grade C, Age 20

Sorted by age (oldest first), then by name:
  Charlie: Grade A, Age 22
  Alice: Grade A, Age 21
  David: Grade C, Age 20
  Bob: Grade B, Age 19
  Frank: Grade A, Age 19
  Eve: Grade B, Age 18

Remarquez comment nous avons utilisé des tuples dans la fonction lambda pour définir plusieurs critères de tri. Le premier élément du tuple est la clé de tri principale, et les éléments suivants sont utilisés pour départager.

Nous avons utilisé un signe négatif -student["age"] pour trier par âge par ordre décroissant. Cette technique est utile lorsque vous souhaitez trier numériquement par ordre inverse.

Tri d'objets personnalisés

Créons un dernier exemple pour montrer comment trier des objets de classe personnalisés. Créez un fichier appelé sorting_objects.py :

## Sorting objects of a custom class
class Person:
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height  ## in cm

    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age}, height={self.height}cm)"

## Create a list of Person objects
people = [
    Person("Alice", 25, 165),
    Person("Bob", 30, 180),
    Person("Charlie", 22, 175),
    Person("David", 35, 170),
    Person("Eve", 28, 160)
]

print("Original list of people:")
for person in people:
    print(f"  {person}")

## Sort by age
by_age = sorted(people, key=lambda person: person.age)
print("\nSorted by age:")
for person in by_age:
    print(f"  {person}")

## Sort by height
by_height = sorted(people, key=lambda person: person.height)
print("\nSorted by height:")
for person in by_height:
    print(f"  {person}")

## Sort by name length, then by age
by_name_length_then_age = sorted(people, key=lambda person: (len(person.name), person.age))
print("\nSorted by name length, then by age:")
for person in by_name_length_then_age:
    print(f"  {person}")

Exécutez ce fichier :

python3 sorting_objects.py

Vous devriez voir :

Original list of people:
  Person(name='Alice', age=25, height=165cm)
  Person(name='Bob', age=30, height=180cm)
  Person(name='Charlie', age=22, height=175cm)
  Person(name='David', age=35, height=170cm)
  Person(name='Eve', age=28, height=160cm)

Sorted by age:
  Person(name='Charlie', age=22, height=175cm)
  Person(name='Alice', age=25, height=165cm)
  Person(name='Eve', age=28, height=160cm)
  Person(name='Bob', age=30, height=180cm)
  Person(name='David', age=35, height=170cm)

Sorted by height:
  Person(name='Eve', age=28, height=160cm)
  Person(name='Alice', age=25, height=165cm)
  Person(name='David', age=35, height=170cm)
  Person(name='Charlie', age=22, height=175cm)
  Person(name='Bob', age=30, height=180cm)

Sorted by name length, then by age:
  Person(name='Bob', age=30, height=180cm)
  Person(name='Eve', age=28, height=160cm)
  Person(name='Alice', age=25, height=165cm)
  Person(name='David', age=35, height=170cm)
  Person(name='Charlie', age=22, height=175cm)

Cet exemple montre comment les fonctions lambda peuvent être utilisées pour trier des objets personnalisés en accédant directement à leurs attributs.

Application de tri en situation réelle

Appliquons maintenant ce que nous avons appris à un scénario d'analyse de données plus réaliste. Nous allons créer un programme qui analyse un ensemble de données de livres et permet le tri selon différents critères.

Créez un fichier appelé book_analyzer.py :

## Book data analysis application
books = [
    {
        "title": "The Great Gatsby",
        "author": "F. Scott Fitzgerald",
        "year": 1925,
        "pages": 180,
        "rating": 4.2,
        "genres": ["Classic", "Fiction"]
    },
    {
        "title": "To Kill a Mockingbird",
        "author": "Harper Lee",
        "year": 1960,
        "pages": 281,
        "rating": 4.3,
        "genres": ["Classic", "Fiction", "Drama"]
    },
    {
        "title": "1984",
        "author": "George Orwell",
        "year": 1949,
        "pages": 328,
        "rating": 4.2,
        "genres": ["Dystopian", "Fiction", "Political"]
    },
    {
        "title": "The Hobbit",
        "author": "J.R.R. Tolkien",
        "year": 1937,
        "pages": 310,
        "rating": 4.4,
        "genres": ["Fantasy", "Adventure"]
    },
    {
        "title": "Harry Potter and the Sorcerer's Stone",
        "author": "J.K. Rowling",
        "year": 1997,
        "pages": 309,
        "rating": 4.5,
        "genres": ["Fantasy", "Adventure", "Young Adult"]
    },
    {
        "title": "The Catcher in the Rye",
        "author": "J.D. Salinger",
        "year": 1951,
        "pages": 214,
        "rating": 3.8,
        "genres": ["Fiction", "Coming of Age"]
    }
]

def print_books(book_list, heading):
    """Helper function to print books in a formatted way"""
    print(f"\n{heading}")
    print("-" * 80)
    for book in book_list:
        genres = ", ".join(book["genres"])
        print(f"{book['title']} by {book['author']} ({book['year']}) - {book['pages']} pages")
        print(f"  Rating: {book['rating']}, Genres: {genres}")
    print("-" * 80)

## Print the original list
print_books(books, "Original Book List")

## Sort books by different criteria
sort_options = {
    "1": ("Title (A-Z)", lambda b: b["title"]),
    "2": ("Author (A-Z)", lambda b: b["author"]),
    "3": ("Publication Year (Oldest First)", lambda b: b["year"]),
    "4": ("Publication Year (Newest First)", lambda b: -b["year"]),
    "5": ("Rating (Highest First)", lambda b: -b["rating"]),
    "6": ("Number of Pages (Lowest First)", lambda b: b["pages"]),
    "7": ("Number of Genres", lambda b: len(b["genres"])),
}

## Show sorting options
print("\nSorting Options:")
for key, (description, _) in sort_options.items():
    print(f"{key}. {description}")

## Automatically show all sorting examples for this tutorial
for option, (description, sort_key) in sort_options.items():
    sorted_books = sorted(books, key=sort_key)
    print_books(sorted_books, f"Books Sorted by {description}")

Exécutez ce fichier :

python3 book_analyzer.py

Vous verrez les livres triés de plusieurs façons :

Original Book List
--------------------------------------------------------------------------------
The Great Gatsby by F. Scott Fitzgerald (1925) - 180 pages
  Rating: 4.2, Genres: Classic, Fiction
To Kill a Mockingbird by Harper Lee (1960) - 281 pages
  Rating: 4.3, Genres: Classic, Fiction, Drama
1984 by George Orwell (1949) - 328 pages
  Rating: 4.2, Genres: Dystopian, Fiction, Political
The Hobbit by J.R.R. Tolkien (1937) - 310 pages
  Rating: 4.4, Genres: Fantasy, Adventure
Harry Potter and the Sorcerer's Stone by J.K. Rowling (1997) - 309 pages
  Rating: 4.5, Genres: Fantasy, Adventure, Young Adult
The Catcher in the Rye by J.D. Salinger (1951) - 214 pages
  Rating: 3.8, Genres: Fiction, Coming of Age
--------------------------------------------------------------------------------

Sorting Options:
1. Title (A-Z)
2. Author (A-Z)
3. Publication Year (Oldest First)
4. Publication Year (Newest First)
5. Rating (Highest First)
6. Number of Pages (Lowest First)
7. Number of Genres

Books Sorted by Title (A-Z)
...

[Output continues with all the different sorting examples]

Cet exemple montre comment les fonctions lambda peuvent être utilisées dans une application réelle pour fournir des capacités de tri flexibles. Remarquez comment nous avons stocké les fonctions lambda avec leurs descriptions dans un dictionnaire, ce qui faciliterait l'ajout d'options de tri supplémentaires dans une application réelle.

Créons une version interactive où l'utilisateur peut choisir une option de tri. Créez un fichier appelé interactive_book_sorter.py :

## Interactive book sorter application
books = [
    {
        "title": "The Great Gatsby",
        "author": "F. Scott Fitzgerald",
        "year": 1925,
        "pages": 180,
        "rating": 4.2,
        "genres": ["Classic", "Fiction"]
    },
    {
        "title": "To Kill a Mockingbird",
        "author": "Harper Lee",
        "year": 1960,
        "pages": 281,
        "rating": 4.3,
        "genres": ["Classic", "Fiction", "Drama"]
    },
    {
        "title": "1984",
        "author": "George Orwell",
        "year": 1949,
        "pages": 328,
        "rating": 4.2,
        "genres": ["Dystopian", "Fiction", "Political"]
    },
    {
        "title": "The Hobbit",
        "author": "J.R.R. Tolkien",
        "year": 1937,
        "pages": 310,
        "rating": 4.4,
        "genres": ["Fantasy", "Adventure"]
    },
    {
        "title": "Harry Potter and the Sorcerer's Stone",
        "author": "J.K. Rowling",
        "year": 1997,
        "pages": 309,
        "rating": 4.5,
        "genres": ["Fantasy", "Adventure", "Young Adult"]
    },
    {
        "title": "The Catcher in the Rye",
        "author": "J.D. Salinger",
        "year": 1951,
        "pages": 214,
        "rating": 3.8,
        "genres": ["Fiction", "Coming of Age"]
    }
]

def print_books(book_list, heading):
    """Helper function to print books in a formatted way"""
    print(f"\n{heading}")
    print("-" * 80)
    for book in book_list:
        genres = ", ".join(book["genres"])
        print(f"{book['title']} by {book['author']} ({book['year']}) - {book['pages']} pages")
        print(f"  Rating: {book['rating']}, Genres: {genres}")
    print("-" * 80)

## Define our sorting options
sort_options = {
    "1": ("Title (A-Z)", lambda b: b["title"]),
    "2": ("Author (A-Z)", lambda b: b["author"]),
    "3": ("Publication Year (Oldest First)", lambda b: b["year"]),
    "4": ("Publication Year (Newest First)", lambda b: -b["year"]),
    "5": ("Rating (Highest First)", lambda b: -b["rating"]),
    "6": ("Number of Pages (Lowest First)", lambda b: b["pages"]),
    "7": ("Number of Genres", lambda b: len(b["genres"])),
}

## Print the original list
print_books(books, "Book Catalog")

while True:
    ## Show sorting options
    print("\nHow would you like to sort the books?")
    for key, (description, _) in sort_options.items():
        print(f"{key}. {description}")
    print("0. Exit")

    choice = input("\nEnter your choice (0-7): ")

    if choice == "0":
        print("Thank you for using the Book Sorter. Goodbye!")
        break
    elif choice in sort_options:
        description, sort_key = sort_options[choice]
        sorted_books = sorted(books, key=sort_key)
        print_books(sorted_books, f"Books Sorted by {description}")
    else:
        print("Invalid choice. Please try again.")

Exécutez cette version interactive :

python3 interactive_book_sorter.py

Cela vous permettra de sélectionner différentes options de tri et de voir les résultats. Lorsque vous avez terminé, entrez "0" pour quitter le programme.

L'application interactive montre comment les fonctions lambda facilitent la mise en œuvre de diverses options de tri dans une application réelle. Chaque option de tri est simplement une fonction lambda qui extrait les informations pertinentes du dictionnaire de livres.

Résumé

Félicitations pour avoir terminé ce tutoriel sur l'utilisation des fonctions lambda pour le tri personnalisé en Python. Vous avez appris :

  1. Les bases des fonctions lambda et comment elles diffèrent des fonctions régulières
  2. Comment utiliser les fonctions lambda avec les fonctions de tri de Python (sorted() et .sort())
  3. Des techniques pour trier différentes structures de données :
    • Listes de valeurs simples
    • Listes de tuples
    • Listes de dictionnaires
    • Objets personnalisés
  4. Le tri multi-niveaux en utilisant des tuples dans les fonctions lambda
  5. Comment appliquer les fonctions lambda dans une application d'analyse de données en situation réelle

Ces compétences seront incroyablement utiles pour le traitement, l'analyse et la manipulation des données dans vos futurs projets Python. Les fonctions lambda offrent un moyen concis et puissant de personnaliser le comportement de tri, rendant votre code plus expressif et plus facile à maintenir.

Au fur et à mesure que vous poursuivrez votre parcours Python, vous constaterez que les fonctions lambda sont utiles non seulement pour le tri, mais aussi pour d'autres fonctions d'ordre supérieur telles que map(), filter() et reduce(). Les techniques que vous avez apprises dans ce tutoriel serviront de base solide pour ces applications plus avancées.