Post

Python Set

Python Set

Set(집합)


Set은 중복을 허락하지 않는다.

파이썬의 Set은 중복된 데이터를 허용하지 않으며, 중복된 요소가 추가되더라도 자동으로 하나의 값만 유지한다.

  • 요소 추가하기 (add)
  • 요소 삭제하기 (remove, discard)
  • 요소가 존재하는지 확인 (in)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 요소 추가하기(add)
my_set = {1, 2, 3}
my_set.add(4)
my_set.add(2)  # 중복된 값 추가 시 무시됨
print(my_set)  # {1, 2, 3, 4}

# 요소 삭제하기(remove, discard)
my_set.remove(2)   # 2 삭제, 없으면 에러 발생
my_set.discard(4)  # 4 삭제 시도, 없으면 무시됨(에러 없음)
print(my_set)      # {1, 3}

# 요소 존재 확인하기(in)
print(1 in my_set)  # True
print(5 in my_set)  # False


in list 보다 in set을 쓰는 이유

파이썬에서 특정 요소가 존재하는지 여부를 빠르게 확인하려면, 리스트(list)보다 셋(set)을 사용하는 것이 성능상 효율적이다.

  • 리스트의 in 연산은 모든 요소를 처음부터 끝까지 순차적으로 확인하여 O(n)의 시간이 걸리지만, 셋의 in 연산은 해시(hash) 방식을 사용하여 평균적으로 O(1)의 상수 시간에 처리할 수 있기 때문이다.
  • 데이터가 많을수록 Set을 활용한 in 연산이 훨씬 빠르게 동작한다.


부분집합을 허용하지 않는다.

부분집합으로 중복없는 조합의 수를 구하려다 TypeError: unhashable type: 'set' 이라는 에러를 마주했다.
수학에 부분집합이라는 개념이 있는데 왜 파이썬의 집합에는 집합을 넣을 수 없는가..?


  • 파이썬에서 객체가 집합(set)의 원소 또는 딕셔너리(dict)의 키(key)가 되기 위해서는 반드시 해시 가능(hashable)해야 한다.
    • 해시 가능하다는 것은 객체가 불변성(immutability)을 가지고, 객체의 해시값(__hash__())이 변하지 않음을 의미한다.
    • 예를 들어 정수(int), 문자열(str), 튜플(tuple)이 해시 가능한 객체이다.


해시값(Hash)

  • 어떤 객체가 가진 값을 빠르게 조회할 수 있도록 그 객체의 내용을 기반으로 생성한 고정된 길이의 숫자값을 말한다.
  • 파이썬에서는 내부적으로 객체마다 __hash__()라는 메서드를 가지고 있으며, 이를 통해 객체가 가진 고유한 값을 계산하여 해시값을 얻는다.
  • 그래서 숫자나 문자열 같은 불변(immutable) 객체는 같은 값이라면 항상 같은 해시값을 가진다.


  • 파이썬의 set은 mutable(변경 가능한) 객체이다.
    • 한 번 만든 집합에 새로운 원소를 추가하거나 삭제할 수 있기 때문에, 그 내용물이 바뀔 때마다 해시값도 바뀌게 된다.
  • mutable 객체는 값이 변하기 때문에 해시값이 안정적으로 유지될 수 없고, __hash__ 메서드를 구현하고 있지 않아 다른 set의 원소로 들어갈 수 없다.

  • 부분집합 형태의 데이터를 요소로 추가하고 싶다면, 변경이 불가능한(immutable) 자료형인 frozenset을 사용해야 한다.
This post is licensed under CC BY 4.0 by the author.