Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Python - Sắp xếp list đầu tiên dựa trên list thứ hai

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}đ")