<개인공부>/[Python]

[python] 파이썬 set (집합) 자료형 정리 및 예제

BlockDMask 2020. 12. 18. 00:30
반응형

안녕하세요. BlockDMask 입니다.
오늘은 파이썬에서 집합 자료형인 set 자료형에 대해서 이야기 해보려 합니다.
집합 자료형은 다른 자료형의 중복 제거할때 사용을 하기도 하는데요.
자세한것은 예제와 설명에서 말씀드리겠습니다. 그럼 시작하겠습니다.

<목차>
1. 집합(set)이란?
2. 집합(set) 교집합, 합집합, 차집합, 집합이 같은지, 다른지
3. 집합(set) 관련 함수들 add, update, remove, clear, in, len, discard, pop 
4. 집합(set) 예제 


1. 파이썬 집합이란?


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

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

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

세개 다 같은 집합을 만듭니다.

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


자 이제 set의 정의 부분을 한번보면 위와 같이 선언이 가능하다는것을 알려주고 있습니다. (공식문서도 동일하겠지만 여기서는 파이참 IDE 를 참고했습니다.)

위 주석을 보게되면
"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(=값이 변하는) 객체 입니다.

*순서가 없기 때문에 리스트나 튜플에서 사용했던 인덱싱이 불가능 한 것 입니다.


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


집합 자료형은 우리가 수학시간에 배웠던 집합의 특징들을 메서드 혹은 연산자를 통해서 구할 수 있게 만들어져있습니다.

2-1) 교집합

1
2
3
4
5
6
7
8
s1 = set([12345])
s2 = set([45678])
 
# 교집합 메서드 intersection
print(s1.intersection(s2))
 
# 교집합 연산자 &
print(s1 & s2)
cs

교집합을 구할때는 "intersection" 이라는 메서드를 이용하거나 "&"를 이용하여 집합의 교집합을 구할 수 있습니다.
예제에서 보면 두 집합에서 같은 값이 있는 4, 5가 잘 나온것을 알 수 있습니다.


2-2) 합집합

1
2
3
4
5
6
7
8
s1 = set([12345])
s2 = set([45678])
 
# 합집합 메서드 union
print(s1.union(s2))
 
# 합집합 연산자 |
print(s1 | s2)
cs

합집합을 구할때는 "union" 이라는 메서드를 이용하거나 "|" 연산자를 이용하여 구할 수 있습니다.
예제의 결과를 보면 양 집합의 모든요소가 합쳐져서 새로운 집합이 만들어 진것을 볼 수 있습니다.


2-3) 차집합

1
2
3
4
5
6
7
8
9
10
11
s1 = set([12345])
s2 = set([45678])
 
# 차집합 메서드 difference
print(s1.difference(s2))
print(s2.difference(s1))
 
# 차집합 연산자 -
print(s1 - s2)
print(s2 - s1)
 
cs

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


2-4) 집합이 같은지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s1 = set([12345])
s2 = set([45678])
s3 = {12345}
 
if s1 == s2:
    print("s1과 s2은 같습니다.")
else:
    print("s1과 s2은 다릅니다.")
 
if s1 == s3:
    print("s1과 s3은 같습니다.")
else:
    print("s1과 s3은 다릅니다.")
 
cs

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
s1 = set([12345])
s2 = set([45678])
s3 = {12345}
s4 = {678910}
 
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은 같은 요소가 적어도 하나는 있습니다.")
cs

집합이 다른것은 사실 요소가 하나라도 다르면 다른것 입니다. 그것에 대한검사는 != 으로 할수 있습니다.
하지만, 여기서 확인하고 싶은것은 집합에서 공통된 부분이 하나도 없다.
즉, 교집합이 없다.
즉, 아예 모든 요소가 다 다르다.
태생부터 이놈과 저놈은 공통점이 없는 다른 집합이다.
라는 것을 알고 싶을때 사용하는 것 입니다. 그때 사용하는 메서드는 isdisjoint 입니다.


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


3. 파이썬 집합 add, update, remove, discard, pop, clear, in, len


3-1) set add - 요소 추가

1
2
3
4
5
6
7
8
9
10
11
12
= {123}
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}')
 
cs

set.add() 메서드를 이용하면 집합 내부에 원하는 값을 추가 할 수 있습니다.
예제에서 확인하셨듯이 중복 값을 넣어도 무시되는 것을 알 수 있습니다.
 이는 집합의 특징인 "중복 제거"에 의해 만들어진 결과이며, 중복된 값을 넣어도 오류가 발생하지 않는다는 것을 알 수 있습니다.


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

1
2
3
4
5
6
7
8
9
= {123}
print(f'set : {s}')
 
s.update({'a''b''c'})
print(f'set : {s}')
 
s.update([111213])
print(f'set : {s}')
 
cs

set.update() 메서드를 이용하면 집합의 값을 한번에 여러개 추가 할 수 있습니다.
자세히 보면 요소를 추가할때 리스트를 뜻하는 대괄호[] 혹은 집합 자료형을 뜻하는 중괄호{}를 이용해서 추가하는 것을 볼 수 있습니다.


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

1
2
3
4
5
6
7
8
9
10
= {'kim''lee''park'234}
print(f'집합 : {s}')
 
s.remove("kim")
print(f'집합 : {s}')
 
# 에러 발생
# s.remove("kim")
# print(f'집합 : {s}')
 
cs

set.remove() 메서드를 이용하면 집합의 특정 요소를 제거 할 수 있습니다.
하지만 지우려는 요소가 집합 안에 없는 경우에는 에러가 발생합니다.
정리하면 set.remoe() 메서드는 아래와 같이 동작합니다.
set 내부에 값이 있으면 삭제
set 내부에 값이 없으면 오류


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

1
2
3
4
5
6
7
8
9
= {'kim''lee''park'234}
print(f'집합 : {s}')
 
s.discard("lee")
print(f'집합 : {s}')
 
s.discard("lee")
print(f'집합 : {s}')
 
cs

이렇게 set.discard() 메서드를 이용하면 안전하게 요소를 제거 할 수 있습니다.
집합의 discard 메서드는 아래와 같이 동작합니다
집합 내부에 값이 있으면 삭제.
집합 내주에 값이 없으면 아무일도 일어나지 않음.


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
= {'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}')
cs

이렇게 set.pop() 메서드를 사용하면 set의 임의의 요소 하나를 반환하고, 그 반환한 요소를 set에서 제거 합니다.

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


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

1
2
3
4
5
6
= {'e''f''g'111213}
print(f'집합 s : {s}')
 
s.clear()
print(f'clear 후 집합 : {s}')
 
cs

집합.clear() 를 이용해서 집합 내부의 모든 요소를 제거 할 수 있습니다.
모든 요소를 제거한 집합은 비어있는 집합이 되며, print를 했을때 는 "set()"으로 표현 됩니다.
len() 으로 집합의 길이를 검사하게 되면 집합의 길이는 0이 나오게 됩니다.


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

1
2
3
4
5
6
7
8
9
10
11
= {'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"가 존재하지 않습니다.')
cs

이렇게 파이썬의 in 을 이용해서 집합 내부에 해당 요소가 있는지 확인할 수 있습니다.


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

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

1,2,3,1,2,3 이 있지만 set으로 만드는 순간 중복이 제거 되어서 만들어 집니다. 그렇기 때문에 {1,2,3}이라는 집합이 생기고 그것을 len 내장함수를 이용해서 길이를 구합니다.
이렇게 파이썬의 내장함수인 len()을 이용해서 집합의 길이를 구할 수 있습니다.


4. 파이썬 집합 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 집합 중복 제거
print('1. 집합 선언시 중복 제거됨')
s1 = {112233'a''a''BlockDMask''BlockDMask''b'}
print(f"s1 : {s1}")
 
 
# 리스트 중복 제거 후 다시 리스트로
print()
print('2. 리스트 중복을 set으로 제거, 그 후 다시 리스트로')
 
result1 = [11111'a''a''list''list'111]
print(f'list = {result1}')
 
s2 = set(result1)
print(f'set(리스트) = {s2}')
print(f'list(집합) = {list(s2)}')
 
 
# 튜플 중복 제거 후 다시 리스트로
print()
print('3. 튜플 중복을 set으로 제거, 그 후 다시 리스트로')
 
result2 = (2233'blog''blog''blockdmask''blockdmask')
print(f'tuple = {result2}')
 
s3 = set(result2)
print(f'set(튜플) = {s3}')
print(f'tuple(집합) = {tuple(s3)}')
 
cs

이렇게 리스트나 튜플의 중복을 제거하기 위해 set 자료형을 이용하기도 합니다.
위에서 말씀드린것과 같이 리스트와 튜플에 순서가 있어도 set 자료형으로 바뀐후에 가기 때문에 set 자료형으로 변경될때 순서가 바뀔 수 있습니다. 그렇기 때문에 다시 본인의 리스트, 튜플로 돌아왔을때 중복은 제거가 되지만, 순서는 보장할 수 없습니다.


이상으로 파이썬 집합 자료형에 대해 작성해보았습니다. 감사합니다.

반응형