155 lines
4.2 KiB
Python
155 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Examples of sorting in Python.
|
|
|
|
This file demonstrates various sorting methods:
|
|
- Basic sorting with sorted() and .sort()
|
|
- Key-based sorting (key=)
|
|
- Custom sorting functions
|
|
- Sorting complex structures (list of dictionaries)
|
|
- Stable sorting
|
|
"""
|
|
|
|
from typing import List, Dict, Tuple, Any
|
|
from operator import itemgetter, attrgetter
|
|
|
|
|
|
# --- Basic Examples ---
|
|
|
|
# 1. Sorting a list with sorted() (returns a new list)
|
|
numbers: List[int] = [3, 1, 4, 1, 5, 9, 2, 6, 5]
|
|
sorted_numbers: List[int] = sorted(numbers)
|
|
print("Sorting with sorted():", sorted_numbers)
|
|
print("Original list unchanged:", numbers)
|
|
|
|
# 2. Sorting a list with .sort() (modifies the original list)
|
|
numbers.sort()
|
|
print("Sorting with .sort():", numbers)
|
|
|
|
|
|
# --- Key-based Sorting ---
|
|
|
|
# 3. Sorting strings by length
|
|
words: List[str] = ["apple", "banana", "cherry", "date", "fig"]
|
|
sorted_by_length: List[str] = sorted(words, key=len)
|
|
print("\nSorting strings by length:", sorted_by_length)
|
|
|
|
# 4. Sorting a dictionary by keys
|
|
data: Dict[str, int] = {
|
|
"banana": 3,
|
|
"apple": 2,
|
|
"pear": 1,
|
|
"orange": 4
|
|
}
|
|
sorted_items: List[Tuple[str, int]] = sorted(data.items(), key=lambda x: x[0])
|
|
print("\nSorting dictionary by keys:", sorted_items)
|
|
|
|
# 5. Sorting a dictionary by values
|
|
sorted_by_value: List[Tuple[str, int]] = sorted(data.items(), key=lambda x: x[1])
|
|
print("Sorting dictionary by values:", sorted_by_value)
|
|
|
|
|
|
# --- Custom Sorting Functions ---
|
|
|
|
# 6. Sorting by last letter
|
|
def sort_by_last_letter(word: str) -> str:
|
|
"""Return the last letter of a word for sorting."""
|
|
return word[-1]
|
|
|
|
|
|
sorted_by_last_letter: List[str] = sorted(words, key=sort_by_last_letter)
|
|
print("\nSorting by last letter:", sorted_by_last_letter)
|
|
|
|
|
|
# --- Sorting Complex Structures ---
|
|
|
|
# 7. Sorting a list of dictionaries
|
|
people: List[Dict[str, Any]] = [
|
|
{"name": "Alice", "age": 30},
|
|
{"name": "Bob", "age": 25},
|
|
{"name": "Charlie", "age": 35},
|
|
{"name": "David", "age": 25}
|
|
]
|
|
|
|
# Sorting by age
|
|
sorted_by_age: List[Dict[str, Any]] = sorted(people, key=lambda x: x["age"])
|
|
print("\nSorting people by age:", sorted_by_age)
|
|
|
|
# Sorting by name
|
|
sorted_by_name: List[Dict[str, Any]] = sorted(people, key=lambda x: x["name"])
|
|
print("Sorting people by name:", sorted_by_name)
|
|
|
|
# 8. Sorting by multiple criteria (age, then name)
|
|
sorted_by_age_then_name: List[Dict[str, Any]] = sorted(
|
|
people, key=itemgetter("age", "name")
|
|
)
|
|
print("\nSorting by age, then by name:", sorted_by_age_then_name)
|
|
|
|
|
|
# --- Stable Sorting ---
|
|
|
|
# 9. Stable sorting (preserves order of equal elements)
|
|
# Python uses Timsort, which is stable
|
|
|
|
# Add unique identifier to demonstrate stability
|
|
people_with_id: List[Dict[str, Any]] = [
|
|
{"name": "Alice", "age": 30, "id": 1},
|
|
{"name": "Bob", "age": 25, "id": 2},
|
|
{"name": "Charlie", "age": 35, "id": 3},
|
|
{"name": "David", "age": 25, "id": 4}
|
|
]
|
|
|
|
# First sort by name
|
|
sorted_by_name_stable: List[Dict[str, Any]] = sorted(
|
|
people_with_id, key=lambda x: x["name"]
|
|
)
|
|
print(
|
|
"\nSorting by name (original order for equal ages):",
|
|
sorted_by_name_stable
|
|
)
|
|
|
|
# Now sort by age - order for Bob and David will be preserved
|
|
sorted_by_age_stable: List[Dict[str, Any]] = sorted(
|
|
people_with_id, key=lambda x: x["age"]
|
|
)
|
|
print(
|
|
"Sorting by age (stable, Bob/David order preserved):",
|
|
sorted_by_age_stable
|
|
)
|
|
|
|
|
|
# --- Additional Examples ---
|
|
|
|
# 10. Reverse sorting
|
|
reverse_sorted: List[int] = sorted(numbers, reverse=True)
|
|
print("\nReverse sorting:", reverse_sorted)
|
|
|
|
|
|
# 11. Sorting using __lt__ (for custom classes)
|
|
class Person:
|
|
"""A simple class representing a person with name and age."""
|
|
|
|
def __init__(self, name: str, age: int) -> None:
|
|
self.name = name
|
|
self.age = age
|
|
|
|
def __repr__(self) -> str:
|
|
return f"Person({self.name}, {self.age})"
|
|
|
|
def __lt__(self, other: "Person") -> bool:
|
|
return self.age < other.age
|
|
|
|
|
|
people_objects: List[Person] = [
|
|
Person("Alice", 30),
|
|
Person("Bob", 25),
|
|
Person("Charlie", 35)
|
|
]
|
|
sorted_people: List[Person] = sorted(people_objects)
|
|
print("\nSorting Person objects:", sorted_people)
|
|
|
|
# 12. Sorting using attrgetter
|
|
sorted_by_name_attr: List[Person] = sorted(people_objects, key=attrgetter("name"))
|
|
print("Sorting objects by 'name' attribute:", sorted_by_name_attr)
|