Python for AI, Embedded/Python: Core & Automation

파이썬(Python) 집합(Set) 사용법 총정리: 중복 제거부터 필수 집합 연산자까지

임베디드 친구 2025. 6. 27. 19:55
반응형

지난 포스팅들을 통해 리스트, 튜플, 그리고 키와 값을 매핑하는 딕셔너리까지 파이썬의 대표적인 자료구조들을 섭렵해 보았습니다. 프로그램을 짜다 보면 데이터 집합에서 중복된 값을 칼같이 골라내야 하거나, 두 데이터 그룹 간에 겹치는 부분(교집합) 혹은 서로 다른 부분(차집합)을 빠르게 계산해야 하는 연산 시나리오를 자주 마주하게 됩니다. 이때 리스트로 복잡한 반복문을 돌리는 대신 파이썬이 제공하는 '집합(Set)' 자료형을 꺼내 들면 코드가 몰라보게 간결해지고 연산 속도도 빨라집니다. 수학의 집합 개념을 코드의 세계로 그대로 가져온 집합 자료형의 기초와 조작법을 소프트웨어 공장에서 자세히 짚어드리겠습니다.

Generated by Gemini AI.

📌 핵심 요약 3줄

  • 집합(Set)은 중복을 절대로 허용하지 않으며 요소의 순서가 유지되지 않는 불완전 자료구조로, 다른 언어의 HashSet과 동일한 메커니즘으로 동작합니다.
  • 빈 집합을 선언할 때는 빈 딕셔너리와의 혼선을 막기 위해 중괄호{}가 아닌 반드시 set() 함수를 호출해야 합니다.
  • 합집합(|), 교집합(&), 차집합(-), 대칭 차집합(^) 등 복잡한 수학적 집합 연산을 코드 기호와 전용 메서드로 간단하게 처리할 수 있습니다.

1. 파이썬 집합(Set)의 독특한 3대 특징

집합은 이전에 배운 선형 자료구조들과는 완전히 다른 결의 규칙을 가지고 움직입니다.

  • 중복 불가(Uniqueness): 집합 안에 동일한 값을 아무리 많이 밀어 넣어도 데이터는 오직 단 하나만 살아남습니다.
  • 순서 없음(Unordered): 데이터가 들어간 순서를 전혀 기억하지 않습니다. 이 때문에 방 번호(인덱스)를 이용한 접근(my_set[0])이 원천적으로 불가능합니다.
  • 초고속 멤버십 테스트: 내부적으로 딕셔너리의 키와 같은 해시 테이블 구조를 공유하므로, 내부에 특정 데이터가 존재하는지 검사(in 연산)하는 속도가 리스트와 비교할 수 없을 정도로 빠릅니다.

2. 집합 정의와 빈 집합 생성 시 주의점

집합은 딕셔너리와 똑같이 중괄호{}를 기호로 쓰지만, 키 없이 값만 나열한다는 점에서 구별됩니다.

Python
 
# 1. 중괄호를 활용한 선언
my_set = {1, 2, 3, 4, 5}

# 2. set() 함수로 리스트의 중복을 한방에 제거하며 생성
raw_list = [1, 2, 3, 3, 4, 4, 5]
clean_set = set(raw_list)  # {1, 2, 3, 4, 5}로 압축됨

# [주의] 아무것도 없는 빈 집합을 만들 때 {}를 적으면 빈 딕셔너리가 생성됩니다!
wrong_empty = {}         # <class 'dict'>
correct_empty = set()    # <class 'set'>

3. 데이터 추가와 삭제 공략하기

집합에 데이터를 추가하거나 지울 때 쓰는 메서드들은 예외 상황에 대처하는 방식이 조금씩 다릅니다.

Python
 
sample_set = {1, 2, 3}

# 1. 요소 추가: .add()
sample_set.add(4)     # {1, 2, 3, 4}
sample_set.add(2)     # 이미 2가 있으므로 아무 일도 일어나지 않음

# 2. 요소 제거: .remove() vs .discard()
sample_set.remove(3)   # {1, 2, 4}로 정상 삭제
# sample_set.remove(9) -> 없는 값을 지우려 하면 KeyError 발생하며 프로그램 다운!

sample_set.discard(9)  # 없는 값을 지우라고 해도 에러 없이 조용히 무시하고 통과

# 3. 전체 초기화: .clear()
sample_set.clear()     # 요소를 싹 비우고 빈 집합 set() 상태로 만듦

4. 수학적 집합 연산 완벽 활용법

집합 자료형의 가장 강력한 무기는 기호 연산자와 메서드로 대변되는 다채로운 집합 계산 기능입니다.

📊 집합 연산자 및 메서드 매핑 테이블

연산 종류 코드 기호 전용 메서드 구문 연산 결과 설명
합집합 A | B A.union(B) 두 집합의 모든 요소를 합친 새로운 집합
교집합 A & B A.intersection(B) 두 집합에 공통으로 들어있는 요소만 추출
차집합 A - B A.difference(B) A 집합에서 B 집합과 겹치는 요소를 빼고 남은 데이터
대칭 차집합 A ^ B A.symmetric_difference(B) 교집합 영역을 제외한 양쪽 집합의 가장자리 데이터만 합성

① 집합 연산 코드 예시

Python
 
set_a = {1, 2, 3}
set_b = {3, 4, 5}

print(set_a | set_b)  # 합집합 출력: {1, 2, 3, 4, 5}
print(set_a & set_b)  # 교집합 출력: {3}
print(set_a - set_b)  # 차집합 출력: {1, 2}
print(set_a ^ set_b)  # 대칭 차집합 출력: {1, 2, 4, 5}

② 포함 관계 검사

Python
 
sub = {1, 2}
parent = {1, 2, 3, 4}

# sub가 parent의 부분집합인지 확인
print(sub.issubset(parent))     # 출력: True

# parent가 sub를 품고 있는 상위집합인지 확인
print(parent.issuperset(sub))   # 출력: True

5. 개발을 위한 팁

  • 대형 데이터의 중복 검사는 리스트 대신 무조건 집합으로: 리스트 안에서 특정 데이터가 있는지 검사하는 if item in 리스트: 구문은 리스트의 길이가 길어질수록 처음부터 끝까지 방을 다 뒤져야 하므로 최악의 경우 속도가 뚝 떨어집니다. 반면 집합은 내부에 해시 알고리즘을 사용하므로, 데이터가 1억 개가 들어있어도 if item in 집합: 문장을 실행하면 눈 깜짝할 사이에 유무를 판별해 냅니다. 데이터 탐색이나 필터링이 잦은 로직이라면 리스트를 set()으로 변환해 두고 검사하는 것이 성능 최적화의 기본입니다.
  • 집합 컴프리헨션(Set Comprehension) 활용하기: 리스트나 딕셔너리와 마찬가지로 집합도 컴프리헨션을 지원합니다. 예를 들어 문자열 리스트에서 글자 수가 3개 이상인 단어들만 중복 없이 모으고 싶다면 clean_words = {word for word in words if len(word) >= 3} 형태로 작성할 수 있습니다. 중괄호{} 안에 키-값 쌍(:) 없이 루프를 돌리면 파이썬이 자동으로 집합 구조로 압축해 줍니다.

6. 흔히 하는 실수

  • 인덱싱 및 슬라이싱 시도로 인한 에러: 겉보기에 리스트와 비슷해 보인다고 해서 my_set[0]이나 my_set[:2] 형태로 값에 접근하려고 하면 TypeError: 'set' object is not subscriptable 에러를 만나게 됩니다. 집합 내부의 데이터를 하나씩 순회하거나 꺼내고 싶다면 반드시 for item in my_set: 처럼 반복문을 이용해 추출하거나, list(my_set)을 통해 임시로 리스트형으로 형 변환을 한 뒤 인덱싱을 진행해야 합니다.
  • 가변 객체(리스트, 딕셔너리)를 집합의 원소로 넣는 실수: 집합의 원소들은 고유한 해시 주소값을 가질 수 있는 불변(Hashable) 데이터여야만 합니다. 문자열, 숫자, 튜플 등은 집합의 요소로 당당히 들어갈 수 있지만, 내부 값이 언제든 바뀔 수 있는 리스트[]나 또 다른 딕셔너리{}를 집합의 원소로 넣으려고 하면 TypeError: unhashable type: 'list' 에러가 터집니다. 집합 안에 또 다른 집합을 넣고 싶을 때도 일반 집합 대신 변경 불가능한 집합인 frozenset을 사용해야 안전하게 중첩할 수 있습니다.

💡 맺음말

이번 시간에는 파이썬의 독특하고 강력한 비선형 자료구조인 집합(Set)의 메커니즘과 실무 연산 테크닉을 깔끔하게 마스터해 보았습니다. 중복이 허용되지 않고 순서가 없다는 특징을 단점이 아닌 강력한 무기로 승화시켜 실무 코드의 탐색 성능을 극대화해 보시기 바랍니다.

집합 연산 기호를 쓰다가 연산자 우선순위가 꼬이거나 형 변환 중 궁금한 점이 생기시면 언제든 아래 댓글 창에 질문을 던져주세요. 소프트웨어 공장이 함께 해결해 드리겠습니다. 감사합니다!

반응형