본문 바로가기
C.W.K.
Stream
Lesson 05 of 07 · published

집합 — 중복 없이 빠르게 묻고 계산하기

~18 min · set, frozenset, membership, set-math

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

값 자체가 곧 구성원인 모음

집합은 해시 가능한 값을 중복 없이 담아. 빈 집합은 set()으로 만들고, {}는 빈 딕셔너리라는 점을 조심해. 순서를 계약하지 않으므로 위치로 접근하지 않아.

멤버십과 집합 연산

집합의 멤버십 검사는 평균 O(1)이라 리스트의 O(n) 검색보다 반복 확인에 유리해. 합집합, 교집합, 차집합, 대칭차집합은 연산자와 메서드 둘 다 제공하며, 부분집합·상위집합 관계도 바로 물을 수 있어.

중복 제거와 frozenset

set(items)은 중복을 없애지만 입력 순서는 잃어. 첫 등장 순서를 보존하려면 삽입 순서를 지키는 딕셔너리 키를 이용해 list(dict.fromkeys(items))로 만들어. frozenset은 바뀌지 않고 해시 가능해서 딕셔너리 키나 다른 집합의 원소가 될 수 있어.

원칙: 순서보다 “들어 있나?”와 집합 관계가 중요하면 set을 먼저 떠올려.

Code

집합 만들기와 빈 집합 함정·python
# 리터럴
s = {1, 2, 3}

# iterable 에서 — dedup 도 해줘
s = set([1, 2, 2, 3, 3, 3])
print(s)                  # {1, 2, 3}

# 빈 set — {} 가 아니라 set()
empty = set()             # 빈 SET
empty_dict = {}           # 빈 DICT

print(type(empty))        # <class 'set'>
print(type(empty_dict))   # <class 'dict'>
집합과 리스트의 멤버십 비용·python
import time

big_list = list(range(1_000_000))
big_set = set(big_list)

start = time.perf_counter()
result = 999_999 in big_list      # O(n)
print("list:", time.perf_counter() - start)

start = time.perf_counter()
result = 999_999 in big_set       # O(1)
print("set:", time.perf_counter() - start)
# list 가 보통 수천 배 느림
합집합·교집합·차집합 계산·python
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# 합집합
print(a | b)              # {1, 2, 3, 4, 5, 6}
print(a.union(b))         # 같음

# 교집합
print(a & b)              # {3, 4}
print(a.intersection(b))  # 같음

# 차집합
print(a - b)              # {1, 2}
print(a.difference(b))    # 같음

# 대칭차 — 정확히 한쪽에만
print(a ^ b)              # {1, 2, 5, 6}

# 부분집합 / 상위집합
print({1, 2} <= a)        # True
print(a >= {1, 2})        # True
첫 등장 순서를 지키며 중복 제거하기·python
items = ["apple", "banana", "apple", "cherry", "banana"]

# set() 은 dedup 하지만 순서 잃어
print(set(items))                 # 순서 안 정해짐

# 유니크 + 순서? dict.fromkeys() — dict 는 순서 보장
print(list(dict.fromkeys(items))) # ['apple', 'banana', 'cherry']  — 첫 등장 순서
해시 가능한 frozenset·python
# 일반 set 은 hashable 하지 않음
edge_lookup = {}
try:
    edge_lookup[{1, 2}] = "edge"
except TypeError as e:
    print(e)              # unhashable type: 'set'

# frozenset 은 hashable
edge_lookup[frozenset({1, 2})] = "edge A"
edge_lookup[frozenset({2, 3})] = "edge B"

# 순서 무관 — 같은 엣지
print(edge_lookup[frozenset({2, 1})])    # 'edge A'

External links

Exercise

users_2024 = ['alice', 'bob', 'charlie', 'dave']users_2025 = ['bob', 'charlie', 'eve', 'frank']에서 두 해 모두 활동한 사람, 2024년에만 활동한 사람, 2025년에만 활동한 사람, 정확히 한 해만 활동한 사람을 집합 연산으로 구해. 출력할 때는 정렬된 리스트로 바꿔.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.