세트 사용하기

Tasker_Jang·2026년 2월 24일

1. 세트란?

파이썬은 수학의 집합을 표현하는 세트(set)라는 자료형을 제공합니다. {} 중괄호 안에 값을 저장하며, 각 값은 ,(콤마)로 구분합니다.

fruits = {"apple", "banana", "cherry"}
print(fruits)  # {'cherry', 'apple', 'banana'} (순서가 다를 수 있음)

세트에는 세 가지 핵심 특성이 있습니다.

특성설명
순서 없음출력할 때마다 요소의 순서가 달라질 수 있음
중복 불가같은 값은 하나만 저장됨
인덱싱 불가[] 대괄호로 특정 요소에 접근할 수 없음
# 중복된 값은 자동으로 제거됨
s = {1, 2, 2, 3, 3, 3}
print(s)  # {1, 2, 3}

# 인덱싱 불가
# print(s[0])  # TypeError!

세트 만들기

# 중괄호로 생성
s1 = {1, 2, 3}

# set()으로 반복 가능한 객체를 넣어 생성
s2 = set([1, 2, 3])        # 리스트로부터
s3 = set("hello")           # 문자열로부터 → {'h', 'e', 'l', 'o'}
s4 = set(range(5))           # range로부터

# ⚠️ 빈 세트는 반드시 set()을 사용
empty_set = set()    # ✅ 빈 세트
empty_dict = {}      # ❌ 이것은 빈 딕셔너리!

⚠️ 세트 안에 세트는 들어갈 수 없습니다. 세트의 요소는 해시 가능(hashable)한 불변 객체만 가능하기 때문입니다. 세트를 요소로 넣고 싶다면 frozenset을 사용해야 합니다.

특정 값 확인 — in, not in

세트는 인덱싱이 불가능하므로, 특정 값이 있는지 확인하려면 in 연산자를 사용합니다.

s = {1, 2, 3, 4, 5}
print(3 in s)      # True
print(10 not in s)  # True

2. 집합 연산

세트의 가장 강력한 기능은 집합 연산입니다. 연산자와 메서드 두 가지 방식을 모두 지원합니다.

연산연산자메서드설명
합집합\|union()두 세트의 모든 요소
교집합&intersection()두 세트에 공통으로 있는 요소
차집합-difference()한쪽에만 있는 요소
대칭 차집합^symmetric_difference()한쪽에만 있는 요소 (양방향)
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# 합집합: 두 세트의 모든 요소
print(a | b)   # {1, 2, 3, 4, 5, 6}

# 교집합: 공통 요소
print(a & b)   # {3, 4}

# 차집합: a에만 있는 요소
print(a - b)   # {1, 2}

# 대칭 차집합: 한쪽에만 있는 요소
print(a ^ b)   # {1, 2, 5, 6}

집합 연산 후 할당

집합 연산 결과를 바로 할당하는 할당 연산자도 사용할 수 있습니다.

할당 연산자동일한 메서드
\|=update()
&=intersection_update()
-=difference_update()
^=symmetric_difference_update()
a = {1, 2, 3}
a |= {4, 5}       # a.update({4, 5})와 동일
print(a)           # {1, 2, 3, 4, 5}

a &= {1, 2, 6}    # a.intersection_update({1, 2, 6})와 동일
print(a)           # {1, 2}

3. 부분집합과 상위집합

부분집합 (subset)

세트 a의 모든 요소가 세트 b에 포함되면, ab부분집합입니다.

a = {1, 2}
b = {1, 2, 3, 4}

# 부분집합 확인
print(a <= b)          # True
print(a.issubset(b))   # True

# 진부분집합: 부분집합이면서 같지 않을 때
print(a < b)   # True  (a는 b의 진부분집합)
print(a < a)   # False (자기 자신은 진부분집합이 아님)

상위집합 (superset)

세트 b가 세트 a의 모든 요소를 포함하면, ba상위집합입니다.

a = {1, 2}
b = {1, 2, 3, 4}

# 상위집합 확인
print(b >= a)            # True
print(b.issuperset(a))   # True

# 진상위집합: 상위집합이면서 같지 않을 때
print(b > a)   # True
print(b > b)   # False

같은지 비교 & 겹치는지 확인

a = {1, 2, 3}
b = {1, 2, 3}
c = {4, 5, 6}

# 세트가 같은지 확인
print(a == b)   # True
print(a != c)   # True

# disjoint: 두 세트가 겹치지 않는지 확인
print(a.isdisjoint(c))  # True  (겹치는 요소 없음)
print(a.isdisjoint(b))  # False (겹치는 요소 있음)

4. 요소 추가와 삭제

메서드기능요소가 없을 때
add(요소)요소 하나 추가
remove(요소)특정 요소 삭제KeyError 발생
discard(요소)특정 요소 삭제그냥 넘어감
pop()임의의 요소 삭제 후 반환KeyError 발생 (빈 세트)
clear()모든 요소 삭제
s = {1, 2, 3}

# add: 요소 추가
s.add(4)
print(s)  # {1, 2, 3, 4}

# remove: 삭제 (없으면 에러)
s.remove(4)
print(s)  # {1, 2, 3}
# s.remove(99)  # KeyError!

# discard: 삭제 (없어도 에러 없음)
s.discard(99)  # 에러 없이 넘어감
print(s)       # {1, 2, 3}

# pop: 임의의 요소 삭제 후 반환
value = s.pop()
print(value)  # 1, 2, 3 중 하나 (예측 불가)

# clear: 모든 요소 삭제
s.clear()
print(s)  # set()

💡 요소가 존재하는지 확실하지 않다면 remove 대신 discard를 사용하는 것이 안전합니다.

len — 요소 개수

s = {1, 2, 3, 4, 5}
print(len(s))  # 5

5. 세트의 할당과 복사

이전 포스트에서 다룬 리스트, 딕셔너리와 마찬가지로, 세트도 할당과 복사에 차이가 있습니다.

# 할당: 같은 세트를 공유
a = {1, 2, 3}
b = a
b.add(4)
print(a)  # {1, 2, 3, 4} ← a도 변경됨!

# 복사: 독립된 세트
a = {1, 2, 3}
b = a.copy()
b.add(4)
print(a)  # {1, 2, 3} ← a는 변경되지 않음

6. 반복문과 세트 컴프리헨션

반복문으로 순회

세트는 순서가 없으므로, 반복문으로 출력할 때 순서가 매번 달라질 수 있습니다.

s = {"apple", "banana", "cherry"}

for item in s:
    print(item)
# 출력 순서는 매번 다를 수 있음

세트 컴프리헨션

for 반복문과 if 조건문을 사용하여 세트를 생성할 수 있습니다. 리스트 컴프리헨션과 문법이 동일하지만, [] 대신 {}를 사용합니다.

# 기본 세트 컴프리헨션
squares = {x ** 2 for x in range(5)}
print(squares)  # {0, 1, 4, 9, 16}

# if 조건 추가
even_squares = {x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares)  # {0, 4, 16, 36, 64}

💡 세트 컴프리헨션의 결과는 중복이 자동으로 제거됩니다. 이 특성을 활용하면 리스트의 중복 제거에도 유용합니다.

# 리스트의 중복 제거에 활용
numbers = [1, 2, 2, 3, 3, 3, 4]
unique = {x for x in numbers}
print(unique)  # {1, 2, 3, 4}

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글