[Python] set 자료형

·2023년 4월 21일
0

1. Python 집합이란?

집합에 관련된 것을 처리 하기 위해 만들어진 자료형

set 키워드 사용하거나 중괄호를 이용해 표현할 수 있다.

s1 = set({1,2,3,})
s2 = set([1,2,3])
s3 = {1,2,3}

세개 다 같은 집합을 만든다.

비어있는 집합을 만들기 위해서는 아래와 같이 사용한다.
s4 = set()

set 정의 부분을 한번 보면 위와 같이 선언이 가능하단 것을 알려주고 있다.

def __init__(self, seq=()): # known special case of set.__init__
	"""
    set() -> new empty set object
    set(iterable) -> new set object 
    Build an unordered collection of unique elements.
    # (copied from class doc)
    """

위 주석을 보게 되면
"set() -> new empty set object"라 하며 set()으로 선언하게 되면 새로운 비어있는 set 객체를 생성한다고 나와있다.

"set(iterable) -> new set object" 이것을 보면 set을 생성할 때 인자로 iterable한 객체를 집어넣게 되면 그걸 이용해서 set 객체가 생성 한다고 나와와있다.
set([1,2,3]), set({1,2,3}) 처럼 선언하는 경우를 말한다.

마지막 줄에는 중요한 set의 특징을 알려준다. unordered하고 unique elements하다.
순서가 정해져있지 않고, 중복되지 않는 고유한 요소들을 가지고 있는 자료형이다.

집합의 특징 정리

  • set() 키워드 혹은 중괄호를 이용한다.
  • 순서가 없다
  • 고유한 값을 가진다. (값 중복 불가능)
  • mutable(=값이 변하는) 객체 입니다.
  • 순서가 없기 때문에 list나 tuple에서 사용했던 indexing이 불가능 한 것이다.

2. Python 교집합,합집합,차집합,집합이 같은지, 다른지

집합 자료형은 수학시간에 배운 집합의 특징들을 method 혹은 연산자를 통해 구할 수 있게 만들어져 있다.

2-1) 교집합

s1 = set([1,2,3,4,5])
s2 = set([4,5,6,7,8])

# 교집합 method intersection
print(s1.intersection(s2))

# 교집합 연산자 &
print(s1 & s2)

{4,5}
{4,5}

교집합을 구할 때 "intersection"이라는 method를 이용하거나 "&"을 이용해 집합의 교집합을 구할 수 있다.

2-2) 합집합

s1 = set([1,2,3,4,5])
s2 = set([4,5,6,7,8])

# 합집합 method union
print(s1.union(s2))

# 합집합 연산자 &
print(s1 | s2)

{1,2,3,4,5,6,7,8}
{1,2,3,4,5,6,7,8}

합집합을 구할 때 "union"이라는 method를 이용하거나 "|"을 이용해 집합의 교집합을 구할 수 있다.

2-3) 차집합

s1 = set([1,2,3,4,5])
s2 = set([4,5,6,7,8])

# 차집합 method difference
print(s1.difference(s2))
print(s2.difference(s1))

# 차집합 연산자 -
print(s1 - s2)
print(s2 - s1)

{1,2,3}
{8,6,7}
{1,2,3}
{8,6,7}

순서가 바뀌어도 상관이 없는 교집합,합집합과 달리 차집합은 순서가 상관이 있다.
차집합을 구할 때 "difference"이라는 method를 이용하거나 "-" 연산자를 이용해서 구할 수 있다.

2-4) 집합이 같은지

s1 = set([1,2,3,4,5])
s2 = set([4,5,6,7,8])
s3 = {1,2,3,4,5}

if s1 == s2:
	print("s1과 s2는 같습니다.")
else:
	print("s1과 s2는 다릅니다.")
    
if s1 == s3:
	print("s1과 s3는 같습니다.")
else:
	print("s1과 s3는 다릅니다.")
    
s1과 s2는 다릅니다.
s1과 s3은 같습니다.

집합은 순서가 상관이 없기 때문에 같은 요소만 들어있다면 같은 집합이다.
집합의 모든요소가 같을때'만' 집합이 같은 것 이다.

2-5) 집합이 아예 다른지 (같은 요소가 없다)

s1 = set([1,2,3,4,5])
s2 = set([4,5,6,7,8])
s3 = {1,2,3,4,5}
s4 = {6,7,8,9,10}

if s1.isdisjoint(s2):
	print("s1과 s2는 같은 요소가 하나도 없습니다.")
else:
	print("s1과 s2는 같은 요소가 적어도 하나는 있습니다.")
    
if s1.isdisjoint(s3):
	print("s1과 s3는 같은 요소가 하나도 없습니다.")
else:
	print("s1과 s3는 같은 요소가 적어도 하나는 있습니다.")
    
if s1.isdisjoint(s4):
	print("s1과 s4는 같은 요소가 하나도 없습니다.")
else:
	print("s1과 s4는 같은 요소가 적어도 하나는 있습니다.")
    

s1과 s2는 같은 요소가 적어도 하나는 있습니다.
s1과 s2는 같은 요소가 적어도 하나는 있습니다.
s1과 s2는 같은 요소가 하나도 없습니다.

집합이 다른것은 사실 요소가 하나라도 다르면 다른것이다. 그것에 대한 검사는 !=으로 할 수 있다.
하지만, 여기서 확인하고 싶은 것은 집합에서 공통된 부분이 하나도 없다.

즉, 교집합이 없다.
즉, 아예 모든 요소가 다 다르다.
태생부터 공통점이 없는 다른 집합이다.
라는 것을 알고 싶을 때 사용하는 것 입니다. 그때 사용하는 method는 isdisjoint 이다.

부분집합을 구하기 위해서는 issubset method를 이용하면 된다.
대칭 차집합을 구하기 위해서는 symmetric_difference method 혹은 "^" 연산자를 이용하면 된다.

Python 집합 add, update, remove, discard, pop, clear, in, len

3-1) set add - 요소 추가

s = {1,2,3}
print(f'set : {s}')

s.add('blockdmask')
print(f'set : {s}')

s.add('blockdmask')  # 중복 값
print(f'set : {s}')

s.add(4)
print(f'set : {s}')




set : {1,2,3}
set : {1,2,3, 'blockdmask'}
set : {1,2,3, 'blockdmask'}
set : {1,2,3, 'blockdmask', 4}

set.add() method 이용하면 집합 내부에 원하는 값을 추가 할 수 있다.
예제에서 본듯이 중복 값을 넣어도 무시된다.
이는 집합의 특징인 "중복 제거"에 의해 만들어진 결과, 중복된 값 넣어도 오류 발생 안한다.

3-2) set update - 요소 여러개 추가

s = {1,2,3}
print(f'set : {s}')

s.update({'a','b','c'})
print(f'set : {s}')

s.update([11, 12, 13])  # 중복 값
print(f'set : {s}')




set : {1,2,3}
set : {1,2,3,'b','c','a'}
set : {1,2,3,'b',11,12,13,'c','a'}

set.update() method 이용하면 집합의 값 한번에 여러개 추가 가능
요소를 추가할 때 리스트를 뜻하는 대괄호, 혹은 집합 자료형을 뜻하는 중괄호를 이용해 추가하는 것을 볼 수 있다.

3-3) set remove - 특정 요소 제거

s = {'kim', 'lee', 'park', 2,3,4}
print(f'집합 : {s}')

s.remove("kim")
print(f'집합 : {s}')

# 에러 발생
# s.remove("kim")
# print(f'집합 : {s}')

집합 : {2,3,4,'lee','kim','park'}
집합 : {2,3,4,'lee','park'}

set.remove() method를 이용하면 집합의 특정 요소를 제거할 수 있다.
하지만 지우려는 요소 집합 안에 없는 경우 에러 발생
set 내부에 값이 있으면 삭제
set 내부에 값이 없으면 오류

3-4) set discard - 특정 요소 안전하게 제거

s = {'kim', 'lee', 'park', 2,3,4}
print(f'집합 : {s}')

s.discard("lee")
print(f'집합 : {s}')

s.discard("lee")
print(f'집합 : {s}')


집합 : {2,3,4,'lee','kim','park'}
집합 : {2,3,4,'kim','park'}
집합 : {2,3,4,'kim','park'}

set.discard() method 이용하면 안전하게 요소 제거할 수 있다
내부 값이 있으면 삭제
내부 값이 없으면 아무일도 일어나지 않음

3-5) set pop - 임의의 요소를 갖고 온 후 제거

s = {'r','a','n','d','o','m'}
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

print(f'집합.pop() : {s.pop()}')
print(f'집합 : {s}')

# 이미 비어있는 집합이므로 pop 불가, error 발생
# print(f'집합.pop() : {s.pop()}')
# print(f'집합 : {s}')


집합 : {'d','n','a','r','o','m'}
집합.pop() : d

집합 : {'n','a','r','o','m'}
집합.pop() : n

집합 : {'a','r','o','m'}
집합.pop() : a

집합 : {'r','o','m'}
집합.pop() : r

집합 : {'o','m'}
집합.pop() : o

집합 : {'m'}
집합.pop() : m

집합 : set()

set.pop() method 사용하면 set의 임의의 요소 하나 반환하고, 그 반환한 요소를 set에서 제거 한다.

  1. set.pop() 함수는 임의의 요소 하나 반환, 반환한 요소 제거
  2. 임의의 요소라고 하지만 자세히 보면 set 맨 앞에 있는 요소를 pop 하고 제거하는걸로 보인다. 하지만 임의의 요소라 하는게 맞는게, set 자료형이 순서가 없는 자료형이기 때문에 맨 앞의 요소라고 해도, 그것이 실제로는 순서가 없는 것이므로 임의의 요소라는 것이 맞다.
  3. set이 비어있는 상태에서는 pop() method 호출하면 에러 발생. 그러므로 len 내장함수 같은걸 이용해 집합이 비어있는지 확인한 후에 set.pop() method를 사용하는것이 안전

3-6) set clear - 모든 요소 제거

s = {'e','f','g',11,12,13}
print(f'집합 s : {s}')

s.clear()
print(f'clear 후 집합 : {s}')

집합 s : {'e','f','g',11,12,13}
clear 후 집합 : set()

집합.clear() 이용해 집합 내부의 모든 요소 제거할 수 있다.
모든 요소 제거한 집합은 비어있는 집합이 되고 print 하면 "set()"으로 표현
len()으로 집합의 길이 검사하게 되면 집합의 길이 0으로 나온다.

3-7) set in - 내부에 요소가 있는지 확인

s = {'a','b','c','d'}

if 'a' in s:
	print('집합 s 내부에 "a"가 존재합니다.')
else:
	print('집합 s 내부에 "a"가 존재하지 않습니다.')
    
if 'z' in s:
	print('집합 s 내부에 "z"가 존재합니다.')
else:
	print('집합 s 내부에 "z"가 존재하지 않습니다.')
    

집합 s 내부에 "a"가 존재합니다.
집합 s 내부에 "z"가 존재하지 않습니다.

3-8) set len - 집합 길이 확인

# 집합 길이 확인
s = {1,2,3,1,2,3}
print(f'집합 : {s}')
print(f'집합의 길이 : {len(s)}')

집합 : {1,2,3}
집합의 길이 : 3

1,2,3,1,2,3 있지만 set으로 만드는 순간 중복은 제거되서 {1,2,3} 집합이 생기고
len 이 3으로 나온다.

4. 예제

# 집합 중복 제거
print('1. 집합 선언시 중복 제거됨')
s1 = {1, 1, 2, 2, 3, 3, 'a', 'a', 'BlockDMask', 'BlockDMask', 'b'}
print(f"s1 : {s1}")
 
 
# 리스트 중복 제거 후 다시 리스트로
print()
print('2. 리스트 중복을 set으로 제거, 그 후 다시 리스트로')
 
result1 = [1, 1, 1, 1, 1, 'a', 'a', 'list', 'list', 1, 1, 1]
print(f'list = {result1}')
 
s2 = set(result1)
print(f'set(리스트) = {s2}')
print(f'list(집합) = {list(s2)}')
 
 
# 튜플 중복 제거 후 다시 리스트로
print()
print('3. 튜플 중복을 set으로 제거, 그 후 다시 리스트로')
 
result2 = (2, 2, 3, 3, 'blog', 'blog', 'blockdmask', 'blockdmask')
print(f'tuple = {result2}')
 
s3 = set(result2)
print(f'set(튜플) = {s3}')
print(f'tuple(집합) = {tuple(s3)}')


1. 집합 선언 시 중복 제거됨
s1 : {1,2,3,'b','BlockDMask','a'}

2. 리스트 중복을 set으로 제거, 그 후 다시 리스트로
list = [1, 1, 1, 1, 1, 'a', 'a', 'list', 'list', 1, 1, 1]
set(리스트) = {1,'list','a'}
list(집합) = [1,'list','a']

3. 튜플 중복을 set으로 제거, 그 후 다시 리스트
tuple = (2, 2, 3, 3, 'blog', 'blog', 'blockdmask', 'blockdmask')
set(튜플) = {'blog','blockdmask',2,3}
tuple(집합_ = ('blog','blockdmask',2,3)

list 나 tuple의 중복 제거하기 위해 set 자료형 이용하기도 한다.
list와 tuple 순서 있어도 set 자료형으로 바뀐후에 가기 때문에 set 자료형으로 변경될 때 순서가 바뀔 수 있다. 그래서 list, tuple 돌아왔을때 중복은 제거가 되지만 순서는 보장할 수 없다.

출처 - https://blockdmask.tistory.com/451

0개의 댓글