Введение
Лямбда-функции (lambda functions) в Python предоставляют лаконичный и мощный способ выполнения пользовательских операций сортировки. В этом руководстве мы рассмотрим, как использовать лямбда-функции для сортировки данных в Python, открывая новые возможности для манипулирования данными и их анализа. К концу вы получите прочное понимание использования лямбда-функций для пользовательской сортировки и сможете применять эти методы в своих собственных проектах на Python.
Понимание лямбда-функций
В Python лямбда-функция (lambda function) — это небольшая анонимная функция, определенная с помощью ключевого слова lambda. В отличие от обычных функций, использующих ключевое слово def, лямбда-функции могут быть созданы встраиваемым способом и не требуют отдельного определения.
Давайте создадим новый файл Python, чтобы изучить лямбда-функции. Откройте WebIDE и создайте новый файл с именем basic_lambda.py в каталоге /home/labex/project/lambda_sorting.
Добавьте следующий код в 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)}")
Теперь давайте запустим этот файл в терминале:
python3 basic_lambda.py
Вы должны увидеть вывод, подобный этому:
Using regular function: 5² = 25
Using lambda function: 5² = 25
3 + 4 = 7
Лямбда-функции особенно полезны, когда вам нужна простая функция на короткий период времени, особенно при использовании таких функций, как map(), filter() или sorted(). Давайте создадим еще один пример, чтобы увидеть лямбда-функции в действии с функцией map().
Создайте новый файл с именем lambda_with_map.py со следующим содержимым:
## 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}")
Запустите этот файл:
python3 lambda_with_map.py
Вы должны увидеть:
Original numbers: [1, 2, 3, 4, 5]
Squared numbers: [1, 4, 9, 16, 25]
Doubled numbers: [2, 4, 6, 8, 10]
Понимание лямбда-функций необходимо, прежде чем мы применим их к сортировке. На следующем шаге мы рассмотрим, как использовать лямбда-функции с функциями сортировки Python.
Базовая сортировка с лямбда-функциями
Python предоставляет два основных способа сортировки коллекций: функцию sorted() и метод .sort() для списков. Мы можем использовать лямбда-функции с обоими для создания пользовательской логики сортировки.
Давайте создадим новый файл с именем basic_sorting.py, чтобы изучить базовую сортировку с лямбда-функциями:
## 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}")
Запустите этот файл:
python3 basic_sorting.py
Вы должны увидеть вывод, подобный:
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']
Параметр key в sorted() принимает функцию, которая преобразует каждый элемент перед сравнением. Лямбда-функции предоставляют лаконичный способ создания этих преобразований.
Теперь давайте попробуем сортировку с более сложными структурами данных. Создайте файл с именем 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]}")
Запустите этот файл:
python3 sorting_tuples.py
Вы должны увидеть студентов, отсортированных разными способами:
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
На следующем шаге мы рассмотрим более продвинутые методы сортировки с использованием лямбда-функций.
Продвинутые методы сортировки
Теперь, когда мы понимаем основы, давайте рассмотрим более продвинутые методы сортировки с использованием лямбда-функций.
Сортировка словарей
Словари — распространенная структура данных в Python, и нам часто нужно сортировать списки словарей. Создайте файл с именем 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']}")
Запустите этот файл:
python3 sorting_dictionaries.py
Вы должны увидеть продукты, отсортированные разными способами:
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
Многоуровневая сортировка
Иногда нам нужно сортировать элементы, используя несколько критериев. Например, мы можем захотеть отсортировать студентов сначала по оценке, а затем по возрасту для тех, у кого одинаковая оценка.
Создайте файл с именем 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']}")
Запустите этот файл:
python3 multi_level_sorting.py
Вы должны увидеть:
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
Обратите внимание, как мы использовали кортежи внутри лямбда-функции для определения нескольких критериев сортировки. Первый элемент в кортеже является основным ключом сортировки, а последующие элементы используются для разрешения коллизий.
Мы использовали отрицательный знак -student["age"] для сортировки по возрасту в порядке убывания. Эта техника полезна, когда вы хотите сортировать в числовом порядке в обратном порядке.
Сортировка пользовательских объектов
Давайте создадим последний пример, чтобы показать, как сортировать объекты пользовательских классов. Создайте файл с именем 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}")
Запустите этот файл:
python3 sorting_objects.py
Вы должны увидеть:
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)
Этот пример демонстрирует, как лямбда-функции можно использовать для сортировки пользовательских объектов путем прямого доступа к их атрибутам.
Реальное применение сортировки
Теперь давайте применим то, что мы узнали, к более реалистичному сценарию анализа данных. Мы создадим программу, которая анализирует набор данных о книгах и позволяет сортировать по различным критериям.
Создайте файл с именем 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}")
Запустите этот файл:
python3 book_analyzer.py
Вы увидите книги, отсортированные различными способами:
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]
Этот пример демонстрирует, как лямбда-функции можно использовать в реальном приложении для обеспечения гибких возможностей сортировки. Обратите внимание, как мы хранили лямбда-функции вместе с их описаниями в словаре, что упрощает добавление дополнительных параметров сортировки в реальном приложении.
Давайте создадим интерактивную версию, где пользователь сможет выбрать параметр сортировки. Создайте файл с именем 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.")
Запустите эту интерактивную версию:
python3 interactive_book_sorter.py
Это позволит вам выбрать различные параметры сортировки и увидеть результаты. Когда закончите, введите "0", чтобы выйти из программы.
Интерактивное приложение демонстрирует, как лямбда-функции упрощают реализацию различных параметров сортировки в реальном приложении. Каждый параметр сортировки — это просто лямбда-функция, которая извлекает соответствующую информацию из словаря книги.
Резюме
Поздравляем с завершением этого руководства по использованию лямбда-функций для пользовательской сортировки в Python. Вы узнали:
- Основы лямбда-функций и их отличия от обычных функций
- Как использовать лямбда-функции с функциями сортировки Python (
sorted()и.sort()) - Методы сортировки различных структур данных:
- Списки простых значений
- Списки кортежей
- Списки словарей
- Пользовательские объекты
- Многоуровневую сортировку с использованием кортежей в лямбда-функциях
- Как применять лямбда-функции в реальном приложении для анализа данных
Эти навыки будут невероятно полезны для обработки, анализа и манипулирования данными в ваших будущих проектах на Python. Лямбда-функции предоставляют краткий и мощный способ настройки поведения сортировки, делая ваш код более выразительным и простым в обслуживании.
Продолжая свой путь в Python, вы обнаружите, что лямбда-функции полезны не только для сортировки, но и для других функций высшего порядка, таких как map(), filter() и reduce(). Методы, которые вы изучили в этом руководстве, послужат прочной основой для этих более продвинутых приложений.



