Khi cần sắp xếp các giá trị của list đầu tiên dựa trên thứ tự của list thứ hai, có thể dùng zip() ghép cặp, sorted() sắp xếp theo key, rồi tách ra.
Ví dụ
def sort_by_second_list(values, keys):
"""
Sắp xếp values theo thứ tự của keys.
Args:
values: list giá trị cần sắp xếp
keys: list khóa sắp xếp (cùng độ dài)
Returns:
list: values đã sắp xếp theo keys
"""
if len(values) != len(keys):
raise ValueError("Hai list phải cùng độ dài")
# zip tạo cặp (key, value), sorted sắp xếp theo key, lấy value
return [v for _, v in sorted(zip(keys, values))]
# Test 1
list_1 = ['m', 'o', 'p', 'l', 'k', 'v', 'c', 'e', 'r']
list_2 = [1, 0, 0, 2, 2, 1, 1, 0, 0]
print(f"List 1 (giá trị): {list_1}")
print(f"List 2 (khóa): {list_2}")
sorted_1 = sort_by_second_list(list_1, list_2)
print(f"\nKết quả: {sorted_1}")
# Test 2
list_3 = ['h', 'k', 'l', 'p', 'q', 'p', 'k', 'l', 'h', 'm', 'u', 'z', 'f', 't']
list_4 = [0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 1, 2, 1, 0]
print(f"\nList 3: {list_3}")
print(f"List 4: {list_4}")
sorted_2 = sort_by_second_list(list_3, list_4)
print(f"Kết quả: {sorted_2}")
Kết quả
List 1 (giá trị): ['m', 'o', 'p', 'l', 'k', 'v', 'c', 'e', 'r'] List 2 (khóa): [1, 0, 0, 2, 2, 1, 1, 0, 0] Kết quả: ['e', 'o', 'p', 'r', 'c', 'm', 'v', 'k', 'l'] List 3: ['h', 'k', 'l', 'p', 'q', 'p', 'k', 'l', 'h', 'm', 'u', 'z', 'f', 't'] List 4: [0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 1, 2, 1, 0] Kết quả: ['h', 'h', 'q', 't', 'f', 'k', 'l', 'p', 'u', 'k', 'l', 'm', 'p', 'z']
Giải thích
zip(keys, values)tạo các cặp(key, value).sorted(...)sắp xếp các cặp theo key (phần tử đầu).[v for _, v in ...]trích xuất value theo thứ tự đã sắp xếp.- Sắp xếp ổn định (stable): các phần tử cùng key giữ nguyên thứ tự tương đối.
Sắp xếp giảm dần
def sort_by_second_desc(values, keys):
return [v for _, v in sorted(zip(keys, values), key=lambda x: x[0], reverse=True)]
Sắp xếp nhiều key (tie-breaker)
# Sắp xếp theo key1, nếu bằng thì theo key2 values = ['a', 'b', 'c', 'd'] key1 = [2, 1, 2, 1] key2 = [10, 20, 5, 15] # zip 3 list result = [v for _, _, v in sorted(zip(key1, key2, values))] print(result) # ['c', 'a', 'd', 'b'] - key1=1 trước, trong đó key2 nhỏ trước
In-place sort (sửa đổi list gốc)
def sort_lists_in_place(values, keys):
"""Sắp xếp cả 2 list in-place theo keys."""
paired = list(zip(keys, values))
paired.sort()
keys[:], values[:] = zip(*paired) if paired else ([], [])
v = ['m', 'o', 'p']
k = [1, 0, 0]
sort_lists_in_place(v, k)
print(v) # ['o', 'p', 'm']
print(k) # [0, 0, 1]
Ứng dụng: Sắp xếp dữ liệu theo cột
# Dữ liệu: tên, tuổi, điểm
names = ['Alice', 'Bob', 'Charlie', 'Diana']
ages = [25, 30, 22, 28]
scores = [85, 90, 78, 92]
# Sắp xếp theo điểm giảm dần
sorted_data = sorted(zip(scores, ages, names), reverse=True)
sorted_scores, sorted_ages, sorted_names = zip(*sorted_data)
print("Xếp hạng:")
for i, (name, age, score) in enumerate(zip(sorted_names, sorted_ages, sorted_scores), 1):
print(f" {i}. {name} (tuổi {age}) - {score}đ")