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.