세트(set)란?
파이썬에서 세트는 순서가 없고 중복을 허용하지 않는 자료구조이다. 이는 수학에서의 집합(Set)과 유사한 개념으로, 특정 조건을 만족하는 고유한 원소들의 모음을 의미한다. 세트는 빠른 멤버십 테스트와 집합 연산을 수행할 때 유용하게 사용된다.
구슬을 가지고 있는 주머니를 생각하면 세트 자료구조를 이해하기 더 쉬울 것이다. 서로 다른 구슬을 주머니 안에 넣으면 넣는 순서는 중요하지 않게 된다. 하나의 집합으로 묶여 있을 뿐이다.
세트 생성하기
방법 1: 중괄호 {}를 사용하여 생성
파이썬에서 세트를 생성하는 가장 기본 적인 방법은 중괄호 {}를 사용하는 방식이다. 요소들을 중괄호 {}로 감싸고, 항목들을 쉼표로 분리해 놓으면 된다. 만약 중복된 요소가 있다면 자동으로 중복된 요소를 제거한다.
# 중괄호를 사용한 세트 생성
numbers = {1, 2, 3, 4, 5}
print(numbers) # {1, 2, 3, 4, 5}
방법 2: set() 함수를 사용하여 생성
set() 함수를 사용하여 세트 자료구조를 생성할 수도 있다. 리스트나 튜플과 같은 반복 가능한 객체를 set() 함수에 전달하면 세트가 생성된다. set 함수의 인자로 전달해 준 객체에 중복된 요소가 있다면 중복은 자동으로 제거가 된다.
# set() 함수를 사용한 세트 생성
colors = set(['빨강', '초록', '파랑', '빨강'])
print(colors) # {'빨강', '초록', '파랑'}
빈 세트 생성
빈 세트를 생성할 때는 반드시 set() 함수를 사용해야 한다. 중괄호 {}는 빈 딕셔너리를 생성하기 때문이다.
# 빈 세트 생성
empty_set = set()
print(empty_set) # set()
세트의 크기는 len() 함수로 알 수 있다.
numbers = {2, 1, 3}
len(numbers) # 3
세트를 만들 때 여러 가지 자료형을 섞는 것도 가능하다.
mySet = {0.1, 2, 'Hello', (1, 2, 3)} # ✅
세트의 항복은 순서가 없기 때문에 위치를 가지고 세트의 항목에 접근할 수는 없지만 for 문을 이용해 각 항목에 접근하는 것은 가능하다. 여기서 주의할 점은 항목들이 출력되는 순서는 입력된 순서와 다를 수도 있다는 점이다. 만약 정렬된 순서로 항목을 출력하고 싶다면 sorted() 함수를 사용하면 된다.
# 입력된 순서는 2, 1, 3이지만 출력된 순서는 1, 2, 3이다.
numbers = {2, 1, 3}
for x in numbers:
print(x, end="") # 1 2 3
# 정렬된 순서의 출력을 원하면 sorted() 함수를 사용하자.
for x in sorted(numbers):
print(x, end="") # 1 2 3
해싱(hashing) 이해하기
잠시 ‘해싱(hashing)’이라는 개념을 잠깐 살펴보고 넘어가자. 해싱은 각 객체에 고유한 숫자 코드를 부여해서 쉽게 찾을 수 있게 하는 방법이다. 완벽하게 이해하지 못해도, ‘고유한 식별 번호’ 정도로 생각하면 충분하다.
세트는 모든 요소를 해싱을 이용해서 저장하고 관리하기 때문에, 세트에 들어가는 요소들은 해싱이 가능해야 한다. 파이썬에서 해싱이 가능하다는 것은 해당 객체가 고유한 해시 코드를 가지고 있고, 그 코드가 변경되지 않아야 한다는 뜻이다. 그래서 세트에는 변경 가능한(eg. 리스트) 항목을 넣을 수 없다.
그래서 아래의 코드처럼 세트 안에 변경 가능한 객체인 리스트를 넣으면 에러가 발생한다.
numbers = {1, 2, [3, 4, 5]} # ❌ 에러
세트의 주요 메서드
세트는 다양한 메서드를 제공하여 요소를 추가하거나 제거할 수 있다. 이것이 가능한 이유는 세트는 변경 가능한 객체이기 때문이다. 하지만 세트의 요소에는 순서가 없고, 따라서 인덱스도 없기 때문에 인덱싱이나 슬라이싱 연산은 불가하다.
하나의 요소 추가 - add()
세트에 새로운 요소 하나를 추가한다. 중복된 요소는 추가되지 않는다.
fruits = {'사과', '바나나'}
fruits.add('체리')
print(fruits) # {'사과', '바나나', '체리'}
여러 개의 요소 추가 - update()
세트에 여러개의 새로운 요소를 추가한다. 물론 중복된 요소는 추가되지 않는다.
fruits = {'사과', '바나나'}
fruits.update('체리', '배', '포도')
print(fruits) # {'사과', '바나나', '체리', '배', '포도'}
요소 삭제 - discard(), remove()
둘 모두 세트에서 특정 요소를 제거한다. 다만 discard()는 요소가 존재하지 않아도 에러가 발생하지 않는 반면, remove()는 요소가 존재하지 않으면 KeyError가 발생한다는 점에서 차이가 있다.
fruits = {'사과', '체리', '바나나'}
fruits.remove('바나나')
print(fruits) # {'사과', '체리'}
fruits.discard('바나나') # 바나나가 이미 제거되었지만 에러는 없음
print(fruits) # {'사과', '체리'}
요소 전체 삭제 - clear()
세트의 전체 요소를 삭제한다.
fruits.clear()
print(fruits) # set()
세트의 부분 집합 연산
== 연산자나 =! 연산자를 사용하면 2개의 세트가 같은지에 대한 여부를 검사할 수 있다.
A = {1, 2, 3}
B = {1, 2, 3}
print(A == B) # True
< 연산자와 <= 연산자를 사용하면 세트가 진부분 집합인지, 부분 집합인지를, > 연산자와 >= 연산자를 사용하면 세트가 진상위 집합인지, 상위 집합인지를 검사할 수 있다.
A = {1, 2, 3, 4, 5}
B = {1, 2, 3}
print(B < A) # True
print(B > A) # False
부분 집합 여부를 검사하려면 <= 연산자나 issubset()을 사용하고, 상위 집합 여부를 검사하려면 >= 연산자를 사용하거나 issuperset()을 사용한다.
A = {1, 2, 3, 4, 5}
B = {1, 2, 3}
print(B.issubset(A)) # True
print(A.issuperset(B)) # True
요소가 세트에 포함되어 있는지 확인하려면 in 키워드를 사용하면 된다.
mySet = set("apple")
print("a" in mySet) # True
print("p" not in mySet) # False
세트의 집합 연산
앞서 파이썬의 세트는 수학의 집합의 개념과 비슷하다고 했다. 실제로 세트는 교집합이나 합집합 같은 여러 가지 집합 연산을 지원한다. 우선 아래와 같은 두 개의 집합이 정의되어 있다고 가정하자:
A = {1, 2, 3}
B = {3, 4, 5}
합집합
합집합은 | 연산자나 union() 메소드를 사용하며, 두 세트의 모든 고유한 요소를 포함하는 세트를 생성한다. 물론 중복되는 요소는 제외된다.
union_set = A.union(B)
print(union_set) # {1, 2, 3, 4, 5}
print(A | B) # {1, 2, 3, 4, 5}
교집합
교집합은 & 연산자나 intersection() 메서드를 사용하며, 2개의 집합에서 겹치는 요소들의 세트를 생성한다.
intersection_set = A.intersection(B)
print(intersection_set) # {3}
print(A & B) # {3}
차집합
차집합은 - 연산자나 diffrence() 메소드를 사용하며, 첫 번째 세트에는 존재하지만 두 번째 세트에는 없는 요소들로 구성된 세트를 생성한다.
difference_set = A.difference(B)
print(A - B) # {1, 2}
print(difference_set) # {1, 2}
정리
지금까지 살펴본 것처럼 파이썬의 세트(Set)는 고유한 요소들의 집합을 효율적으로 관리할 수 있는 자료구조이다. 중복 제거, 빠른 멤버십 테스트, 집합 연산 등 다양한 기능을 제공하여 데이터 처리의 효율성을 높여준다. 세트의 특성을 잘 이해하고 상황에 맞게 활용해 보도록 하자.
'Language > Python' 카테고리의 다른 글
[Python] 파이썬의 언패킹 연산자 (0) | 2025.01.20 |
---|---|
[Python] 파이썬 딕셔너리(dictionary) 이해하기 (0) | 2025.01.18 |
[Python] 파이썬 튜플 이해하기 (1) | 2025.01.17 |
[Python] 파이썬 2차원 리스트 (생성, 접근, 활용) (0) | 2025.01.17 |
[Python] 파이썬 리스트 컴프리헨션 (리스트 함축, List Comprehension) (0) | 2025.01.16 |