Python sorted() + key: 5 Cách Sắp Xếp Dữ Liệu Thực Tế Trong Lập Trình

  • Home
  • Python sorted() + key: 5 Cách Sắp Xếp Dữ Liệu Thực Tế Trong Lập Trình

Trong quá trình phát triển ứng dụng web, xử lý dữ liệu hệ thống hay phân tích dữ liệu, việc sắp xếp (sorting) là thao tác diễn ra liên tục. Python cung cấp hàm built-in sorted() cực kỳ mạnh mẽ, nhưng sức mạnh thực sự của nó chỉ bộc lộ khi bạn làm chủ tham số key.

Bài viết này từ DCSoftTech sẽ hướng dẫn chi tiết cú pháp, nguyên lý hoạt động và 5 trường hợp ứng dụng thực tế phổ biến nhất của sorted() kết hợp với key.

1. Tổng Quan Về Hàm sorted() Trong Python

Hàm sorted() nhận vào một cấu trúc dữ liệu có thể lặp (Iterable) như List, Tuple, Dictionary… và trả về một danh sách mới đã được sắp xếp. Điều này giúp giữ nguyên dữ liệu gốc (tránh side-effect).

Cú pháp cơ bản

sorted(iterable, key=None, reverse=False)
  • iterable: Chuỗi, danh sách, tuple, dictionary, set… cần sắp xếp.

  • key: Một hàm (function) nhận vào từng phần tử của iterable và trả về một giá trị làm “tiêu chí” để so sánh.

  • reverse: False (mặc định – tăng dần) hoặc True (giảm dần).

Phân biệt sorted() và list.sort()

  • list.sort() chỉ áp dụng cho đối tượng list, thay đổi trực tiếp danh sách ban đầu (in-place) và trả về None.

  • sorted() áp dụng cho mọi iterable, tạo ra list mới và không làm ảnh hưởng đến dữ liệu cũ.

2. Tham Số key Hoạt Động Như Thế Nào?

Khi bạn truyền tham số key=function_name, Python sẽ:

  1. Áp dụng function_name cho từng phần tử trong danh sách.

  2. Lấy giá trị trả về từ hàm đó làm khóa so sánh (Sort Key).

  3. Sắp xếp các phần tử dựa trên thứ tự của các khóa này.

Bạn có thể truyền vào một hàm có sẵn (như len, str.lower), một hàm tự định nghĩa bằng def, một lambda function, hoặc hàm từ thư viện operator.

3. 5 Cách Sắp Xếp Dữ Liệu Thực Tế Với sorted() + key

Cách 1: Sắp Xếp Chuỗi Theo Độ Dài Hoặc Không Phân Biệt Hoa/Thường

Mặc định, Python sắp xếp chuỗi theo bảng mã ASCII (chữ hoa đứng trước chữ thường). Nhờ tham số key, bạn có thể tùy chỉnh lại theo logic mong muốn.

####Ví dụ 1: Sắp xếp danh sách tên theo độ dài

names = ["Nguyen Van A", "Le B", "Tran Thi Minh C", "Do D"]

# Sắp xếp từ ngắn nhất đến dài nhất
sorted_names = sorted(names, key=len)
print(sorted_names)
# Kết quả: ['Do D', 'Le B', 'Nguyen Van A', 'Tran Thi Minh C']

Ví dụ 2: Sắp xếp không phân biệt hoa/thường (Case-insensitive)

brands = ["apple", "Samsung", "Xiaomi", "ASUS"]

# Không phân biệt chữ hoa/thường
sorted_brands = sorted(brands, key=str.lower)
print(sorted_brands)
# Kết quả: ['apple', 'ASUS', 'Samsung', 'Xiaomi']

Cách 2: Sắp Xếp Danh Sách Dictionary Theo Key Cụ Thể (Làm Việc Với API/Database)

Khi nhận dữ liệu JSON từ API hoặc query từ cơ sở dữ liệu, dữ liệu thường nằm ở dạng List[Dict].

Yêu cầu: Sắp xếp danh sách nhân viên theo độ tuổi tăng dần.

employees = [
    {"name": "Dung", "age": 28, "salary": 1500},
    {"name": "An", "age": 22, "salary": 1200},
    {"name": "Binh", "age": 35, "salary": 2000},
]

# Sử dụng lambda function làm key
sorted_by_age = sorted(employees, key=lambda emp: emp["age"])

print(sorted_by_age)
# Kết quả:
# [
#   {'name': 'An', 'age': 22, 'salary': 1200},
#   {'name': 'Dung', 'age': 28, 'salary': 1500},
#   {'name': 'Binh', 'age': 35, 'salary': 2000}
# ]

Tối ưu hiệu năng: Thay vì dùng lambda, với các tập dữ liệu lớn, bạn nên dùng itemgetter từ module operator để chạy nhanh hơn.

from operator import itemgetter

sorted_by_salary = sorted(employees, key=itemgetter("salary"), reverse=True)

Cách 3: Sắp Xếp Đa Tiêu Chí (Multiple Criteria Sorting)

Trong thực tế, bạn thường phải sắp xếp theo tiêu chí ưu tiên 1, nếu bằng nhau thì so sánh tiếp tiêu chí 2.

Yêu cầu: Sắp xếp sinh viên theo Điểm giảm dần, nếu điểm bằng nhau thì sắp xếp theo Tên tăng dần (A-Z).

Ví dụ này trả về một Tuple (-student["score"], student["name"]) trong hàm key:

  • Giá trị âm -student["score"] đảo ngược thứ tự số, giúp điểm cao xếp trước.

  • Tên giữ nguyên dạng chuỗi để xếp theo thứ tự bảng chữ cái.

students = [
    {"name": "Minh", "score": 8.5},
    {"name": "An", "score": 9.0},
    {"name": "Hoa", "score": 8.5},
    {"name": "Binh", "score": 9.0},
]

# Ưu tiên score giảm dần (-), sau đó đến name tăng dần (+)
sorted_students = sorted(
    students, key=lambda s: (-s["score"], s["name"])
)

for s in sorted_students:
    print(f"{s['name']}: {s['score']}")

# Kết quả in ra:
# An: 9.0
# Binh: 9.0
# Hoa: 8.5
# Minh: 8.5

Cách 4: Sắp Xếp Danh Sách Các Class Object (Hướng Đối Tượng)

Khi lập trình OOP, dữ liệu của bạn là các thể hiện (instance) của một class. Bạn có thể dùng key hoặc attrgetter để sắp xếp.

from operator import attrgetter

class Product:

    def __init__(self, name, price, stock):
        self.name = name
        self.price = price
        self.stock = stock

    def __repr__(self):
        return f"Product({self.name}, Price: {self.price}, Stock: {self.stock})"


products = [
    Product("Laptop", 1200, 10),
    Product("Mouse", 25, 50),
    Product("Keyboard", 75, 20),
]

# Sắp xếp danh sách sản phẩm theo giá tăng dần
sorted_products = sorted(products, key=attrgetter("price"))

print(sorted_products)
# Kết quả: [Product(Mouse, Price: 25, Stock: 50), Product(Keyboard, Price: 75, Stock: 20), Product(Laptop, Price: 1200, Stock: 10)]

Cách 5: Sắp Xếp Dictionary Theo Value Hoặc Key Tùy Chỉnh

Dictionary trong Python (từ bản 3.7+) giữ thứ tự thêm vào. Muốn sắp xếp một Dictionary theo giá trị (Value), bạn kết hợp sorted() với .items().

Yêu cầu: Bảng xếp hạng điểm số game, sắp xếp theo điểm cao nhất xuống thấp nhất.

leaderboard = {"player_A": 450, "player_B": 1200, "player_C": 890, "player_D": 1200}

# sorted() trả về danh sách các tuple (key, value)
sorted_tuples = sorted(
    leaderboard.items(), key=lambda item: item[1], reverse=True
)

# Chuyển đổi lại thành Dictionary
sorted_leaderboard = dict(sorted_tuples)

print(sorted_leaderboard)
# Kết quả: {'player_B': 1200, 'player_D': 1200, 'player_C': 890, 'player_A': 450}

4. Best Practices & Lưu Ý Khi Sử Dụng key Của DCSoftTech

  1. Ưu tiên operator.itemgetter / attrgetter cho dữ liệu lớn: Dùng hàm trong module operator sẽ tối ưu về mặt hiệu năng (C-speed) tốt hơn so với gọi lambda function trong các tập dữ liệu có hàng trăm ngàn bản ghi.

  2. Kỹ thuật đổi dấu - cho dữ liệu số: Khi cần sắp xếp đa tiêu chí mà có tiêu chí tăng, tiêu chí giảm, hãy dùng dấu - cho các trường dữ liệu kiểu số (int, float).

  3. Tính ổn định của thuật toán (Stable Sort): Python sử dụng thuật toán Timsort. Nó đảm bảo nếu hai phần tử có giá trị key bằng nhau, thứ tự xuất hiện ban đầu của chúng sẽ được giữ nguyên.

  4. Tránh xử lý logic quá nặng trong key: Hàm key sẽ chạy $N$ lần (với $N$ là số lượng phần tử). Tránh việc query DB hoặc gọi API bên trong hàm key.

Lời Kết

Làm chủ hàm sorted() và tham số key sẽ giúp bạn viết mã nguồn Python ngắn gọn, tinh tế và tối ưu hơn rất nhiều. Từ việc sắp xếp danh sách cơ bản đến xử lý các cấu trúc dữ liệu phức tạp trong các dự án thực tế, sorted() luôn là công cụ hàng đầu.

Hy vọng bài viết thủ thuật Python này từ DCSoftTech hữu ích cho công việc lập trình của bạn!

Categories:

Leave Comment