set은 순서 없는, 유일 값의 봉지예요
리스트와 튜플이 순서를 신경 쓰는 반면, set은 그렇지 않아요. 리스트는 중복을 쌓아두지만, set은 조용히 버려요. 두 가지 욕구가 있을 때 set이 적절한 자료구조예요:
- 유일한 아이템만 원해요, 단호하게.
- 멤버십을 빠르게 검사하고 싶어요.
중괄호로 씁니다:
두 번째 set의 중복된 "red"와 "green"은 그냥 사라져요. 에러가 아니에요 — 그게 바로 set이 하는 일이에요.
집합 만들기
실제로 쓰게 될 두 가지 방법:
마지막 포인트는 누구나 한 번씩 걸려요: {}는 빈 _딕셔너리_를 만들지, 빈 set이 아닙니다. 문법적 모호성을 어느 한쪽에 몰아줘야 했고, dict가 이겼어요.
추가와 제거
remove vs discard가 핵심 차이예요: remove는 아이템이 반드시 있어야 하고, discard는 상관하지 않아요. 아이템이 없는 게 에러인지 아닌지에 따라 골라 쓰세요.
빠른 멤버십 검사
여기서 set이 본격적으로 진가를 발휘해요. x in some_set은 set이 아무리 커도 상수 시간에 동작해요. x in some_list는 리스트를 훑어야 해서 리스트가 크면 느려집니다.
어림짐작: 반복문 안에서 if x in some_list를 쓰고 있는데 리스트가 수십 개를 넘어간다면, 먼저 리스트를 set으로 바꾸세요.
집합 수학
여기가 set이 진짜 재미있어지는 지점이에요. 수학의 집합 연산을 그대로 따르는 연산자들로 집합을 결합할 수 있어요:
각 연산자에는 메서드 형태도 있어요(.union(), .intersection(), .difference(), .symmetric_difference()). 연산자는 더 간결하고, 메서드 형태는 꼭 set이 아니어도 어떤 이터러블이든 받습니다.
리스트 중복 제거
"집합 논리" 밖에서도 set의 가장 흔한 용도 중 하나예요:
한 줄, 중복 삭제. 단 하나: 순서가 유지되지 않아요. 유일성 과 원래 순서가 둘 다 필요하다면 dict.fromkeys()를 쓰세요:
현대 파이썬에서 dict는 삽입 순서를 유지하고, dict.fromkeys는 이터러블의 아이템을 키로 삼아 dict를 만들어요 — 사실상 순서 있는 set이 됩니다.
부분집합과 상위집합
한 집합이 다른 집합에 포함되는지 검사하기:
권한 검사("이 사용자가 필요한 역할을 다 가졌나?") 같은 데서 등장해요.
set에 들어갈 수 있는 것
해시 가능(hashable) 한 것들만이에요. 기술 용어인데, 실제로는 이런 뜻이에요:
- 불변인 건 해시 가능: 숫자, 문자열, 해시 가능한 원소들만 가진 튜플, frozenset.
- 가변인 건 불가능: 리스트, dict, 다른 set은 원소로 들어갈 수 없어요.
set의 set이 필요하면 frozenset을 쓰세요 — set의 불변 버전이에요.
순회는 순서가 없어요
set을 반복하면 아이템의 순서가 보장되지 않아요:
몇 번 돌려보면 순서가 들쑥날쑥한 걸 볼 수 있어요. 순서가 중요하다면 set은 맞는 구조가 아니에요 — 필요할 때 내용을 정렬하거나 리스트를 쓰세요.
set을 쓰지 말아야 할 때
다음 중 하나라도 해당되면 리스트나 dict가 더 나아요:
- 순서가 중요할 때.
- 중복을 보관해야 할 때.
- 각 아이템에 연관된 데이터가 있을 때(아이템을 키로 삼은 dict를 쓰세요).
다음으로
set은 유일성과 멤버십을 담당해요. 다음은 딕셔너리예요 — "키로 값을 찾는" 더 넓은 패턴을 다루는, 파이썬에서 리스트 다음으로 가장 유용한 자료구조죠.
자주 묻는 질문
파이썬의 set이 뭔가요?
set은 순서 없는 유일 값의 컬렉션이에요. 중괄호를 쓰되 키-값 쌍은 넣지 않아요: colors = {'red', 'green', 'blue'}. 같은 값을 두 번 추가해도 아무 일 없어요 — 중복은 조용히 버려집니다.
언제 리스트 대신 set을 써야 하나요?
유일성이 중요하거나 멤버십 검사(x in collection)를 많이 할 때 set을 쓰세요. set은 중복을 자동으로 제거해 주고, 멤버십 검사가 상수 시간에 끝나요. 큰 컬렉션에서는 리스트보다 엄청나게 빠릅니다.
파이썬에서 빈 집합은 어떻게 만드나요?
set()을 쓰세요. {}가 아니라요 — 아무것도 없는 중괄호는 빈 딕셔너리를 만듭니다, 빈 set이 아니라요. set을 만들고 나면 .add(value)로 아이템을 추가할 수 있어요.