#!/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)