IT/파이썬

[코딩도장] day17. 세트 사용하기(1/2) - set(), issubset(), issuperset(), isdisjoint()

_하늘여우_ 2020. 9. 1. 23:52

■ 들어가기

- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


▶ Unit26. 세트 사용하기

     - 26.1 세트 만들기

     - 26.2 집합 연산 사용하기

     - 26.3 세트 조작하기

     - 26.4 세트의 할당과 복사

     - 26.5 반복문으로 세트의 요소를 모두 출력하기

     - 26.6 세트 표현식 사용하기

 

 

0. 들어가기

- 지금까지 파이썬에서 자료를 다루는 방법으로

- 리스트, 튜플, 딕셔너리를 다루었음

- 이번 시간엔 세트(set)라는 자료형에 대해서 학습

- 합집합, 교집합, 차집할 등의 연산 가능

- 세트 특징

1) 요소들 간의 순서가 없으며 (indexing 불가)

2) 중복 불가

3) 세트 메소드 add(요소 1개 추가), update(여러 요소 추가), remove(요소 삭제) 를 사용하여 요소 조작 가능

4) 합집합: a|b, 교집합: a&b, 차집합: a-b


>> 26.1 세트 만들기 <<

- 표기: {}(중괄호) 안에 값을 저장하며 각 값은 ,(콤마)로 구분

- 사용법 : 세트 = {값1, 값2, 값3}

 

1. 세트에 특정 값이 있는지 확인하기

- 리스트, 튜플, 딕셔너리와 같이 in 연산자 사용

- 사용법1: 값 in 세트

- 특정 값이 있으면 True, 없으면 False

>>> fruits = {'strawberry', 'grape', 'orange', 'pineapple', 'cherry'}
>>> fruits
{'orange', 'strawberry', 'grape', 'pineapple', 'cherry'}
>>> 'orange' in fruits
True
>>> 'peach' in fruits
False

- 사용법2(특정 값이 없는지 확인): 값 not in 세트

- 특정 값이 없으면 True, 있으면 False

>>> 'orange' not in fruits
False
>>> 'peach' not in fruits
True

 

2. set를 사용하여 세트 만들기

- 사용법 : set(반복 가능한 객체)

- 반복 가능한 객체 : 문자열과 range 가능

- 중복된 문자를 입력해도 유일한 문자로만 세트를 만듦

>>> set('apple')
{'e', 'p', 'l', 'a'}
>>> set(range(5))    # 0부터 4까지 숫자를 가진 세트 생성
{0, 1, 2, 3, 4}
>>> c = set()     # 빈 세트 생성
>>> c
set()
>>> d = {}    # 빈 딕셔너리 생성
>>> type(d)
<class 'dict'>
>>> type(c)
<class 'set'>

- 주의1 : {}로만 생성하면 '딕셔너리'로 생성됨, 빈 세트는 반드시 set() 사용!

- 주의2 : 세트 안에 세트를 넣을 수 없음! (리스트, 딕셔너리와의 차이점)

>>> a = {{1, 2}, {3, 4}}
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    a = {{1, 2}, {3, 4}}
TypeError: unhashable type: 'set'

- 주의3 : 일반적인 set는 추가/삭제 등의 수정 가능하지만, frozenset는 생성 후 수정 불가!

  why? frozenset는 세트 안에 세트를 넣고 싶을 때 사용함! (단, 이때도 frozenset일 때만 중첩세트 가능)

>>> a = frozenset(range(10))
>>> a
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
>>> a.add(10)    # 요소 10 추가
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    a.add(10)
AttributeError: 'frozenset' object has no attribute 'add'

>> 26.2 집합 연산 사용하기 <<

- 합집합(union) : 세트1과 세트2의 모든 요소를 중복 제거하여 합침, OR연산자 | 사용

- 사용법

세트1 | 세트2

set.union(세트1, 세트2)

>>> a = {1, 2, 3, 4}
>>> b = {3, 4, 5, 6}
>>> a | b
{1, 2, 3, 4, 5, 6}
>>> set.union(a, b)
{1, 2, 3, 4, 5, 6}

- 교집합(intersection) : 세트1과 세트2에서 겹치는 부분을 구함(즉 중복되는 값만 추출), AND연산자 & 사용

- 사용법

세트1 & 세트2

set.intersection(세트1, 세트2)

>>> a
{1, 2, 3, 4}
>>> b
{3, 4, 5, 6}
>>> a & b
{3, 4}
>>> set.intersection(a, b)
{3, 4}

- 차집합(difference) : 세트1 기준으로 세트1과 세트2 사이에 겹치는(중복된) 요소 제거한 나머지 반환, 뺄셈연산자 - 사용

- 사용법

세트1 - 세트2

set.difference(세트1, 세트2)

>>> a
{1, 2, 3, 4}
>>> b
{3, 4, 5, 6}
>>> a - b
{1, 2}
>>> set.difference(a, b)
{1, 2}

- 대칭차집합(symmetric defference) : 세트1과 세트2 중에서 겹치는(중복된) 요소 제거한 모든 요소를 합함, XOR연산자 ^ 사용

- 사용법

세트1 ^ 세트2

set.symmetric_difference(세트1, 세트2)

>>> a
{1, 2, 3, 4}
>>> b
{3, 4, 5, 6}
>>> a ^ b
{1, 2, 5, 6}
>>> set.symmetric_difference(a, b)
{1, 2, 5, 6}

 

1. 집합 연산 후 할당 연산자 사용하기

- 세트 자료형(|, &, -, ^)에 집합 연산 후 할당 연산자(=)을 함께 사용하면, 집합 연산의 결과를 변수에 다시 저장(할당)

<< 합집합 후 할당 >> 사용법

세트1 |= 세트2

세트1.update(세트2)

>>> a
{1, 2, 3, 4}
>>> a |= {5}    # 세트 a 와 세트 5를 합친 후 이를 다시 세트 a 에 저장
>>> a
{1, 2, 3, 4, 5}
>>> b
{3, 4, 5, 6}
>>> b.update({7})    # 세트 b 와 세트 7을 합친 후 이를 다시 세트 b 에 저장
>>> b
{3, 4, 5, 6, 7}

<< 교집합 후 할당 >> 사용법

세트1 &= 세트2

세트1.intersection_update(세트2)

>>> a = {1, 2, 3, 4}
>>> a &= {0, 1, 2, 3, 4}     # 세트 a 와 세트 {0, 1, 2, 3, 4} 중 겹치는 {1, 2, 3, 4}를 세트 a 에 저장
>>> a
{1, 2, 3, 4}
>>> b = {1, 2, 3, 4}
>>> b.intersection_update({0, 1, 2, 3, 4})
>>> b
{1, 2, 3, 4}

<< 차집합 후 할당 >> 사용법

세트1 -= 세트2

세트1.defference_update(세트2)

>>> a
{1, 2, 3, 4}
>>> a -= {3}      # 세트 a 와 {3} 중에서 겹치는 {3}을 제외한 나머지 추출
>>> a
{1, 2, 4}
>>> b
{1, 2, 3, 4}
>>> b.difference_update({3})
>>> b
{1, 2, 4}

<< 대칭차집합 후 할당 >> 사용법

세트1 ^= 세트2

세트1.symmetric_difference_update(세트2)

>>> a = {1, 2, 3, 4}
>>> a ^= {3, 4, 5, 6}       # 세트 a 와 {3, 4, 5, 6} 중에서 겹치는 {3, 4}를 제외한 나머지 합침
>>> a
{1, 2, 5, 6}
>>> b = {1, 2, 3, 4}
>>> b.symmetric_difference_update({3, 4, 5, 6})
>>> b
{1, 2, 5, 6}

 

2. 부분 집합과 상위집합 확인하기

- 지금까지 합집합(OR), 교집합(AND), 차집합(-), 대칭차집합(XOR)에 대해 학습

  세트는 부분집합, 진부분집합, 상위집합, 진상위집합과 같이 속하는 관계를 표현 가능

- 현재 세트가 다른 세트의 (진)부분집합 또는 (진)상위집합인지 확인 시 세트 자료형에 부등호와 등호를 사용하여 확인 가능

- 부분집합(subset) : 현재 세트가 다른 세트의 부분집합인지 확인

- 사용법

현재세트 <= 다른세트

현재세트.issubset(다른세트)

>>> a = {1, 2, 3, 4}
>>> type(a)
<class 'set'>
>>> a <= {1, 2, 3, 4}
True
>>> a.issubset({1, 2, 3, 4, 5})
True

- 진부분집합(proper subset) : 현재 세트가 다른 세트의 진부분집합인지 확인 (메서드는 없음)

>> 잠깐!

Q) 부분집합과 진부분집합의 차이는??

더보기

A) 어떤 집합의 부분집합 중 처음 집합(자기 자신 집합)을 제외한 나머지 집합들을 진부분집합이라고 표현함

     ex. 집합 {1, 2}의 부분집합 : 공집합, {1}, {2}, {1, 2} // 진부분집합 : 공집합, {1}, {2}

     그래서 부호로 표기 시 부분집합은 등호(=)를 포함하지만 진부분집합엔 등호(=)가 포함되지 않음

- 사용법

현재세트 < 다른세트

>>> a
{1, 2, 3, 4}
>>> a < {1, 2, 3, 4, 5}
True
>>> a < {1, 2, 3, 4}
False

- 상위집합(superset) : 현재 세트가 다른 세트의 상위집합인지 확인

- 사용법

현재세트 >= 다른세트

현재세트.issuperset(다른세트)

>>> a
{1, 2, 3, 4}
>>> a.issubset({})
False
>>> a
{1, 2, 3, 4}
>>> a >= {1, 2, 3, 4}
True
>>> a >= {1}
True
>>> a >= {}     # 비어있는 세트를 표기하기 위해선 set()를 사용하여야 함. {}만 지정 시 빈 딕셔너리로 지정됨.
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    a >= {}
TypeError: '>=' not supported between instances of 'set' and 'dict'
>>> a >= set()
True
>>> a
{1, 2, 3, 4}
>>> a.issuperset({1, 2, 3, 4})
True

- 진상위집합(proper superset) : 현재 세트가 다른 세트의 진상위집합인지 확인 (메서드는 없음)

- 사용법

현재세트 > 다른세트

>>> a
{1, 2, 3, 4}
>>> a > {1, 2, 3}
True
>>> a > {1, 2, 3, 4, 5}
False

 

3. 세트가 같은지 다른지 확인하기

- 사용법 : == 연산자 사용

  ( 세트는 요소의 순서가 정해지 있지 않으므로 == 비교 시 각 요소만 같으면 참이다. )

>>> a = {1, 2, 3, 4}
>>> type(a)
<class 'set'>
>>> a
{1, 2, 3, 4}
>>> b = {4, 3, 2, 1}
>>> type(b)
<class 'set'>
>>> b
{1, 2, 3, 4}
>>> a == b
True
>>> a == {1, 2, 3, 4}
True

- != 연산자는 세트가 다른지 확인

>>> a
{1, 2, 3, 4}
>>> c = {1, 2, 3}
>>> a != c
True

 

4. 세트가 겹치지 않는지 확인하기

- 사용법 : 현재세트.isdisjoint(다른세트)

- 겹치지 않으면 True, 겹치면 False

>>> a
{1, 2, 3, 4}
>>> a.isdisjoint({5, 6, 7, 8})      # 겹치는 요소가 없음
True
>>> a.isdisjoint({3, 4, 5, 6})      # a와 3, 4가 겹침
False