Khi cần xóa các list trùng lặp bên trong một tuple (tuple của các list) đồng thời giữ nguyên thứ tự xuất hiện, có thể sử dụng list comprehension kết hợp với set để theo dõi đã thấy.
List comprehension là cú pháp ngắn gọn để duyệt và xử lý list.
Kiểu set chỉ chứa các phần tử duy nhất, hữu ích cho các phép toán tập hợp.
Vì list không hash được (unhashable), cần chuyển thành tuple trước khi đưa vào set.
Ví dụ
def remove_duplicate_lists(tuple_of_lists):
"""
Loại bỏ list trùng lặp trong tuple, giữ thứ tự xuất hiện đầu tiên.
"""
seen = set()
result = []
for lst in tuple_of_lists:
# Chuyển list -> tuple để có thể hash và kiểm tra trong set
tup = tuple(lst)
if tup not in seen:
seen.add(tup)
result.append(lst)
return result
# Tuple chứa các list
my_tuple = ([1, 21, 34], [11, 0, 98], [45, 67, 56], [11, 0, 98], [1, 21, 34])
print("Tuple ban đầu:")
print(my_tuple)
unique_result = remove_duplicate_lists(my_tuple)
print("\nTuple sau khi loại bỏ list trùng lặp (giữ thứ tự):")
print(unique_result)
Kết quả
Tuple ban đầu: ([1, 21, 34], [11, 0, 98], [45, 67, 56], [11, 0, 98], [1, 21, 34]) Tuple sau khi loại bỏ list trùng lặp (giữ thứ tự): [[1, 21, 34], [11, 0, 98], [45, 67, 56]]
Giải thích
- Tuple gốc chứa 5 list, trong đó [1, 21, 34] và [11, 0, 98] xuất hiện 2 lần.
- Duyệt qua từng list, chuyển thành tuple để kiểm tra trong
seenset. - Chỉ thêm vào kết quả nếu chưa từng thấy.
- Kết quả là list chứa các list duy nhất, giữ thứ tự lần xuất hiện đầu tiên.
Cách ngắn gọn: List comprehension + set (trick)
seen = set()
result = [lst for lst in my_tuple
if not (tuple(lst) in seen or seen.add(tuple(lst)))]
# seen.add() trả về None (falsy), nên `or` chỉ chạy khi tuple(lst) không trong seen
# Khi chạy seen.add(), tuple được thêm vào seen, và biểu thức tổng thể là False
# `not False` = True -> list được giữ
print(result)
Cách này "tricky" và khó đọc, khuyến nghị dùng hàm rõ ràng ở trên.
Nếu không cần giữ thứ tự
# Dùng set trực tiếp (mất thứ tự)
unique = list({tuple(lst) for lst in my_tuple})
# Kết quả: các list duy nhất nhưng thứ tự ngẫu nhiên