How to use a lambda function for custom sorting in Python

PythonPythonBeginner
Practice Now

Introduction

Python's lambda functions offer a concise and powerful way to perform custom sorting operations. In this tutorial, we'll explore how to use lambda functions to sort data in Python, unlocking new possibilities for data manipulation and analysis. By the end, you'll have a solid understanding of leveraging lambda functions for custom sorting and be able to apply these techniques to your own Python projects.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python/ControlFlowGroup -.-> python/conditional_statements("Conditional Statements") python/DataStructuresGroup -.-> python/lists("Lists") python/DataStructuresGroup -.-> python/tuples("Tuples") python/DataStructuresGroup -.-> python/dictionaries("Dictionaries") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/FunctionsGroup -.-> python/lambda_functions("Lambda Functions") python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/conditional_statements -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/lists -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/tuples -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/dictionaries -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/function_definition -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/lambda_functions -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/classes_objects -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} python/data_collections -.-> lab-415786{{"How to use a lambda function for custom sorting in Python"}} end

Understanding Lambda Functions

In Python, a lambda function is a small, anonymous function defined with the lambda keyword. Unlike regular functions that use the def keyword, lambda functions can be created inline and don't need a separate definition.

Let's create a new Python file to explore lambda functions. Open the WebIDE and create a new file called basic_lambda.py in the /home/labex/project/lambda_sorting directory.

Add the following code to 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)}")

Now let's run this file in the terminal:

python3 basic_lambda.py

You should see output like this:

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

Lambda functions are especially useful when you need a simple function for a short period, particularly when using functions like map(), filter(), or sorted(). Let's create another example to see lambdas in action with the map() function.

Create a new file called lambda_with_map.py with the following content:

## 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}")

Run this file:

python3 lambda_with_map.py

You should see:

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

Understanding lambda functions is essential before we apply them to sorting. In the next step, we'll explore how to use lambda functions with Python's sorting functions.

Basic Sorting with Lambda Functions

Python provides two main ways to sort collections: the sorted() function and the .sort() method for lists. We can use lambda functions with both to create custom sorting logic.

Let's create a new file called basic_sorting.py to explore basic sorting with lambda functions:

## 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}")

Run this file:

python3 basic_sorting.py

You should see output like:

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']

The key parameter in sorted() takes a function that transforms each item before comparison. Lambda functions provide a concise way to create these transformations.

Now let's try sorting with more complex data structures. Create a file called 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]}")

Run this file:

python3 sorting_tuples.py

You should see the students sorted in different ways:

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

In the next step, we'll explore more advanced sorting techniques using lambda functions.

Advanced Sorting Techniques

Now that we understand the basics, let's explore more advanced sorting techniques using lambda functions.

Sorting Dictionaries

Dictionaries are a common data structure in Python, and we often need to sort lists of dictionaries. Create a file called 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']}")

Run this file:

python3 sorting_dictionaries.py

You should see the products sorted in different ways:

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

Sometimes we need to sort items using multiple criteria. For example, we might want to sort students first by grade, and then by age for those with the same grade.

Create a file called 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']}")

Run this file:

python3 multi_level_sorting.py

You should see:

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

Notice how we used tuples within the lambda function to define multiple sorting criteria. The first element in the tuple is the primary sorting key, and subsequent elements are used for tie-breaking.

We used a negative sign -student["age"] to sort by age in descending order. This technique is useful when you want to sort numerically in reverse order.

Sorting Custom Objects

Let's create a final example to show how to sort custom class objects. Create a file called 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}")

Run this file:

python3 sorting_objects.py

You should see:

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)

This example demonstrates how lambda functions can be used to sort custom objects by accessing their attributes directly.

Real-World Sorting Application

Now let's apply what we've learned to a more realistic data analysis scenario. We'll create a program that analyzes a dataset of books and allows sorting by different criteria.

Create a file called 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}")

Run this file:

python3 book_analyzer.py

You'll see the books sorted in multiple ways:

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]

This example demonstrates how lambda functions can be used in a real application to provide flexible sorting capabilities. Notice how we stored the lambda functions along with their descriptions in a dictionary, which would make it easy to add more sorting options in a real application.

Let's create an interactive version where the user can choose a sorting option. Create a file called 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.")

Run this interactive version:

python3 interactive_book_sorter.py

This will allow you to select different sorting options and see the results. When you're done, enter "0" to exit the program.

The interactive application demonstrates how lambda functions make it easy to implement various sorting options in a real application. Each sorting option is simply a lambda function that extracts the relevant information from the book dictionary.

Summary

Congratulations on completing this tutorial on using lambda functions for custom sorting in Python. You've learned:

  1. The basics of lambda functions and how they differ from regular functions
  2. How to use lambda functions with Python's sorting functions (sorted() and .sort())
  3. Techniques for sorting different data structures:
    • Lists of simple values
    • Lists of tuples
    • Lists of dictionaries
    • Custom objects
  4. Multi-level sorting using tuples in lambda functions
  5. How to apply lambda functions in a real-world data analysis application

These skills will be incredibly useful for data processing, analysis, and manipulation in your future Python projects. Lambda functions provide a concise and powerful way to customize sorting behavior, making your code more expressive and easier to maintain.

As you continue your Python journey, you'll find that lambda functions are useful not only for sorting but also for other higher-order functions like map(), filter(), and reduce(). The techniques you've learned in this tutorial will serve as a solid foundation for these more advanced applications.