파이썬/기본

[파이썬] 컬렉션 타입, 세트

caramel-bottle 2023. 9. 5.

세트란

중복되지 않는 항목들의 컬렉션이다.

 

set

s1 = {}
print(s1)
print(type(s1)) # {}의 기본형은 딕셔너리

s1 = {1, 3, 5, 7}
print(s1)
print(type(s1))

set은 파이썬 컬렉션 타입중 하나이다. 쉽게 집합이라고 생각하면 좋다.

set의 항목은 중괄호( {} )로 표현하는데 위 코드의 결과를 보면 s1의 타입이 dict로 나오는 것을 볼 수 있다.

사실 컬렉션 타입중 하나인 딕셔너리도 중괄호를 사용한다. 파이썬에서 요소가 없는 중괄호는 딕셔너리로 판단한다는 것을 알 수 있다.

s1 = {1, 3, 5, 7} set의 형태는 쉼표(,)로 구분되어지는 요소들로 표현된다.


list -> set

# list를 set()함수를 통해 set으로 변환
li1 = [1, 3, 5, 7]
s2 = set(li1)
print(s2)
print(type(s2))

list에서도 알아봤듯이 set() 함수를 사용하여 자료구조 변환이 가능하다.

 

# set의 특징, 중복 x
s3 = {1, 3, 5, 3, 7, 9, 1}
print(s3)

# list에서 set으로 변환
li2 = [1, 3, 5, 3, 7, 9, 1]
print(li2)
s4 = set(li2)
print(s4)

이어서 set의 특징이다. set은 중복을 허용하지 않는다. 허용하지 않는다 보단 중복을 없애준다에 더 가까운 것 같다.

또한 순서에 관한 특징이 있다. 얼핏보면 자동정렬인 것 같지만 set에서 순서는 별 의미가 없다고 생각해도 좋다.

 

* set도 pop() 메서드 사용이 가능하다. 순서에 큰 의미는 없지만 pop() 메서드를 사용하려면 주의하길.

 

중복이 있는 list에서 set으로 변환을 하면 중복값이 없는 형태로 변환됨을 확인할 수 있다.


add()

# 값을 원하는 위치에서 뽑지 못한다.
# 순서가 정해져있지 않음.

s1 = {100, 200}
s1.add(150)
print(s1)

s1.add(50)
print(s1)
# 순서가 중요하다면 list나 tuple을 사용할 것

add() 메서드를 사용하여 요소를 추가할 수 있다.

 

인덱스가 없으므로 리스트처럼 인덱싱을 통한 값 변환은 불가능하다. 하지만 추가, 삭제, 복사는 가능하다. 


update()

# update 메서드
s1 = {100, 200}
s1.update([40, 50, 60, 20]) # 괄호에 값들을 묶은 이유: 한번에 묶어서 넣겠다 라는 의미
print(s1)

s1.update((40, 50, 60, 20))
print(s1)

add()는 요소 하나씩 추가하는 메서드이다. 여러 값을 한꺼번에 추가하려면 update() 메서드를 사용한다.

 


remove(), discard()

# remove 메서드
s1 = {10, 20, 30}
s1.remove(20) # in-place 연산
print(s1)

# s1.remove(20) # KeyError: 20

remove() 메서드로 지정한 요소를 지울 수 있다. 

이미 지워진 혹은 없는 값을 입력하면 에러가 발생한다.

없는 값을 입력해도 에러가 발생하지 않게 하려면 예외처리를 해도 되지만 set에는 discard() 메서드가 제공된다.

 

# discard 메서드
s1 = {10, 20, 30}
s1.discard(30)
print(s1)

s1.discard(30) # remove와 다르게 에러가 나지 않는다.
print(s1)

# 지워진 사실을 확인하기 위해선 remove메서드를 사용하는 것이 좋다.

주석에 써놓은 내용처럼 이미 지워졌거나 없는 요소임을 확인하기 위해선 remove() 메소드를 사용하는 것이 좋다.


copy()

# 복사
s1 = {10, 20, 30}
s2 = s1.copy() # 데이터를 복사, 메모리를 다른 곳에 보냄
# s2 = s1 # 주소를 복사

print(s1, id(s1))
print(s2, id(s2))
# 주소가 물리적인 주소는 아님
# 원본 데이터를 유지하고 싶은 경우 copy 사용

copy() 메서드를 통해 데이터를 복사할 수 있다. 유의할 점은 데이터를 복사하여 새로운 객체를 만드는 것이지 주소를 공유하는 것이 아니라는 것이다.

id() 함수를 통해 가리키는 객체가 다른 것을 확인할 수 있다.


set 관련 메서드

union()

# set은 집합을 다룰 때 많이 사용됨
# 그래서 집합 관련된 메서드를 가지고 있음

s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}

result1 = s1.union(s2) # 합집합
print(result1)

result2 = s1 | s2 # OR 연산, 합집합과 동일한 결과
print(result2)

set의 특징은 집합이라는 사실은 메서드를 통해 명확하게 확인이 가능하다.

union() 메서드는 두 set의 합집합을 반환한다.

다른 자료구조와는 다르게 '+' 을 통한 결합이 불가능하고, Or 연산자인 '|'를 통해 합집합 연산이 가능하다.


intersection()

s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}

result1 = s1.intersection(s2) # 교집합
print(result1)

result2 = s1 & s2 # AND 연산, 교집합과 동일한 결과
print(result2)

intersection() 메서드는 교집합을 반환한다.

마찬가지로 And 연산자인 '&'를 통해 같은 결과를 얻을 수 있다.


difference()

s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}

result1 = s1.difference(s2) # 차집합
print(result1)

result2 = s1 - s2 # 차집합과 동일한 결과
print(result2)

result3 = s2.difference(s1)
print(result3)

다음으로 차집합 메서드인 difference() 이다.

합집합과 다르게 '-'연산자를 사용하여 같은 결과를 얻을 수 있다.

이 메서드는 연산 순서에 따라 결과가 다르기 때문에 조심해야한다.


symmetric_difference()

s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}

result1 = s1.symmetric_difference(s2) # 여집합
print(result1)

result2 = s1 ^ s2 # 여집합과 동일한 결과
print(result2)

교집합의 여집합도 구할 수 있다.

'^' 는 비트연산 XOR에 해당하는 연산자인데 set 연산에 사용하면 교집합의 여집합을 얻을 수 있다.

댓글