Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python: หาเซตซ้ำ (Duplicate Sets) ในลิสต์ของเซต

บทนำ

เซต (set) ใน Python เป็น unhashable type ไม่สามารถนำไปใส่ใน set อีกชั้น หรือใช้เป็น key ใน dict ได้ ต้องแปลงเป็น frozenset (immutable set) ก่อนจึงจะนับความถี่ด้วย Counter ได้

ตัวอย่างโค้ด


from collections import Counter

my_list = [{4, 8, 6, 1}, {6, 4, 1, 8}, {1, 2, 6, 2}, {1, 4, 2}, {7, 8, 9}]

print("ลิสต์เซตต้นทาง:")
for i, s in enumerate(my_list):
    print(f"  [{i}] {s}")

# แปลงเป็น frozenset แล้วนับ
freq = Counter(frozenset(s) for s in my_list)

print("\nความถี่:")
for fs, count in freq.items():
    print(f"  {set(fs)}: {count}")

# หาเฉพาะเซตที่ซ้ำ (count > 1)
duplicates = [set(fs) for fs, count in freq.items() if count > 1]
print(f"\nเซตซ้ำ: {duplicates}")

ผลลัพธ์


ลิสต์เซตต้นทาง:
  [0] {8, 1, 4, 6}
  [1] {8, 1, 4, 6}
  [2] {1, 2, 6}
  [3] {1, 2, 4}
  [4] {8, 9, 7}

ความถี่:
  {8, 1, 4, 6}: 2
  {1, 2, 6}: 1
  {1, 2, 4}: 1
  {8, 9, 7}: 1

เซตซ้ำ: [{8, 1, 4, 6}]

เหตุผลที่ต้องใช้ frozenset


# ❌ Error: unhashable type: 'set'
# Counter(my_list)  

# ✅ OK: frozenset เป็น hashable
Counter(frozenset(s) for s in my_list)

วิธีทางเลือก: ใช้ sorted tuple


# แปลงเซตเป็น sorted tuple (hashable)
freq = Counter(tuple(sorted(s)) for s in my_list)
duplicates = [set(t) for t, c in freq.items() if c > 1]
print(duplicates)  # [{1, 4, 6, 8}]

ฟังก์ชันครบถ้วน


def find_duplicate_sets(set_list, return_counts=False):
    """หาเซตซ้ำในลิสต์ของเซต
    
    Args:
        set_list: list of sets
        return_counts: True = คืน (set, count), False = คืน set เท่านั้น
    
    Returns:
        list of duplicate sets (หรือ list of (set, count))
    """
    freq = Counter(frozenset(s) for s in set_list)
    
    if return_counts:
        return [(set(fs), count) for fs, count in freq.items() if count > 1]
    else:
        return [set(fs) for fs, count in freq.items() if count > 1]

# ทดสอบ
dups = find_duplicate_sets(my_list, return_counts=True)
print(dups)  # [({1, 4, 6, 8}, 2)]

กรณีใช้งานจริง

  • ตรวจจับ duplicate records ในข้อมูลที่เป็นเซต (เช่น tags, categories)
  • Deduplication ของ graph edges (undirected)
  • หา feature sets ที่ซ้ำใน ML datasets

สรุป

ใช้ Counter(frozenset(s) for s in set_list) นับความถี่เซต ได้ผลลัพธ์เป็น frozenset แปลงกลับเป็น set ก่อนคืนค่า วิธีนี้ O(n) และจัดการ unhashable nature ของ set ได้อย่างถูกต้อง