파이썬 | 세트 사용하기

CHOI·2021년 11월 20일
0

Python

목록 보기
19/33
post-thumbnail

1. 세트 만들기

세트는 중괄호{} 안에 값을 저장하고 각 값은 콤마 로 구분한다.

  • 세트 = {값1, 값2, 값3}

간단한 예시로 과일이 들어있는 세트를 만들어보겠다.

>>> fruits = {'strawberry', 'grape', 'orange', 'pineapple', 'cherry'}
>>> fruits
{'pineapple', 'orange', 'grape', 'strawberry', 'cherry'}

세트는 요소의 순서가 정해져 있지 않다. 따라서 세트를 출력할 때 마다 매번 출력되는 요소의 순서가 바뀐다.

또한 세트는 요쇼의 중복이 불가능하다. 다음과 같이 'orange' 를 두 번 넣어도 한 개만 들어간 것을 볼 수 있다.

>>> fruits = {'orange', 'orange', 'cherry'}
>>> fruits
{'cherry', 'orange'}

또한 세트는 리스트,튜플,딕셔너리와 다르게 대괄호[] 를 통한 특정 요소의 접근이 불가능하다.

>>> fruits = {'strawberry', 'grape', 'orange', 'pineapple', 'cherry'}
>>> print(fruits[0])
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    print(fruits[0])
TypeError: 'set' object does not support indexing
>>> fruits['strawberry']
Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    fruits['strawberry']
TypeError: 'set' object is not subscriptable

특정 값이 있는지 확인 (in)

그렇다면 특정 값이 있는지 확인하려면 어떻게할까? 이전에 리스트,튜플,딕셔너리에서도 사용했던 in 을 사용하면 된다.

  • 값 in 세트
>>> fruits = {'strawberry', 'grape', 'orange', 'pineapple', 'cherry'}
>>> 'orange' in fruits
True
>>> 'peach' in fruits
False
  • 값 not in 세트
>>> 'peach' not in fruits
True
>>> 'orange' not in fruits
False

물론 특정 값이 없는지 확인하기 위해선 not in 을 사용하면 된다.

set를 사용하여 세트 만들기

이번에는 set 를 사용하여 세트를 만들어보자.

  • set(반복가능한객체)

set 에는 반복 가능한 객체를 넣는다. 반복 가능한 객체는 뒤에서 보자

>>> a = set('apple')    # 유일한 문자만 세트로 만듦
>>> a
{'e', 'l', 'a', 'p'}

set('apple') 과 같이 영문 문자열을 세트로 만들면 중복된 문자를 제외하고 세트가 만들어진다.

>>> b = set(range(5))
>>> b
{0, 1, 2, 3, 4}

위와 같이 range 를 통해서도 세트를 만들 수 있다.

>>> c = set()
>>> c
set()

빈 세트를 만들 때는 위와 같이 만들면 된다.

>>> c = {}
>>> type(c)
<class 'dict'>
>>> c = set()
>>> type(c)
<class 'set'>

단, 주의할 점은 세트가 중괄호{}를 사용한다고 하여 c = {} 를 하면 빈 세트가 아니라 빈 딕셔너리가 만들어지므로 주의해야한다. 위와 같이 type 을 사용하면 자료형의 종류를 알 수 있다.

% 세트 안에 세트 넣기?

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

세트는 리스트나 딕셔너리와 다르게 세트 안에 세트를 넣을 수 없다.

% 프로즌 세트

파이썬에서는 내용을 변경할 수 없는 세트인 프로즌 세트도 제공한다.

>>> a = frozenset(range(10))
>>> a
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})

말 그대로 얼어 있는(frozen) 세트이다. 따라서 요소를 추가하거나 삭제하는 연산, 메서드를 사용할 수 없다.

>>> a = frozenset(range(10))
>>> a |= 10
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    a |= 10
TypeError: unsupported operand type(s) for |=: 'frozenset' and 'int'
>>> a.update({10})
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    a.update({10})
AttributeError: 'frozenset' object has no attribute 'update'

그렇다면 왜 굳이 요소를 변경할 수 없는 프로즌 세트를 사용할까? 프로즌 세트는 세트 안에 세트를 넣고 싶을 때 사용한다. 다음과 같이 frozenset 안에 frozenset 를 중첩해서 사용할 수 있다. 단, 프로즌세트만 가능하지 세트는 불가능하다.

>>> frozenset({frozenset({1, 2}), frozenset({3, 4})})
frozenset({frozenset({1, 2}), frozenset({3, 4})})

2. 집합 연산

이번에는 세트에서 집한 연산과 이에 대응하는 메서드를 사용해보자. 집한 연산은 산술 연산자와 논리 연산자를 사용한다.

집합 연산자

합집합 ( | )

| 연산자는 합집합(union)을 구하며 or 연산자 | 를 사용한다. 이는 set.union 메서드와 동작이 같다.

  • 세트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}

Untitled

교집합 (&)

& 연산자는 교집합(intersection)을 구하며 AND 연산자인 & 를 사용한다. 이는 set.intersection 메서드와 동작이 같다.

  • 세트1 & 세트2
  • set.intersection(세트1, 세트2)
>>> a & b
{3, 4}
>>> set.intersection(a, b)
{3, 4}

Untitled

차집합 ( - )

- 연산자는 차집합(difference) 를 구하며 뺄셈 연산자 - 를 사용한다. 이 동작은 set.differnece 와 동일하다.

  • 세트1 - 세트2
  • set.difference(세트1, 세트2)
>>> a - b
{1, 2}
>>> set.difference(a, b)
{1, 2}

Untitled

대칭차집합 ( ^ )

^ 연산자는 대칭차집합(symmetric difference)를 구하며 XOR 연산자 ^ 를 사용한다. 이 동작은 set.symmetric_difference 와 동일하다.

XOR 은 서로 다르면 참이다. 따라서 두 집합의 겹치지 않는 요소만 포함한다.

  • 세트1 ^ 세트2
  • set.symmetric_difference(세트1, 세트2)
>>> a ^ b
{1, 2, 5, 6}
>>> set.symmetric_difference(a, b)
{1, 2, 5, 6}

Untitled

집합 연산 후 할당 연산자 사용

세트 자료형에 |, &, -, ^ 연산자와 할당 연산자 = 를 같이 쓰면 집합 연산 결과를 다시 변수에 할당한다.

|= 는 현재 세트에 다른 세트를 더하며 update 메서드와 같다.

  • 세트1 |= 세트2
  • 세트1.update(세트2)
>>> a = {1, 2, 3, 4}
>>> a |= {5}
>>> a
{1, 2, 3, 4, 5}
>>> a = {1, 2, 3, 4}
>>> a.update({5})
>>> a
{1, 2, 3, 4, 5}

&= 는 현재 세트와 다른 세트 사이에 겹치는 요소만 현재 세트에 저장하며 intersection_update 메서드와 동일하다.

  • 세트1 &= 세트2
  • 세트1.intersection_update(세트2)
>>> a = {1, 2, 3, 4}
>>> a &= {0, 1, 2, 3, 4}
>>> a
{1, 2, 3, 4}
>>> a = {1, 2, 3, 4}
>>> a.intersection_update({0, 1, 2, 3, 4})
>>> a
{1, 2, 3, 4}

-= 는 현재 세트에 다른 세트를 뺴며 set.difference_update 메서드와 동일하다.

  • 세트1 -= 세트2
  • 세트1.difference_update(세트2)
>>> a = {1, 2, 3, 4}
>>> a -= {3}
>>> a
{1, 2, 4}
>>> a = {1, 2, 3, 4}
>>> a.difference_update({3})
>>> a
{1, 2, 4}

^= 는 현재 세트와 다른 세트의 겹치지 않는 요소만 현재 세트에 저장되며 set.symmetric_difference_update 와 동일하다.

  • 세트1 ^= 세트2
  • 세트1.symmetric_difference_update(세트2)
>>> a = {1, 2, 3, 4}
>>> a ^= {3, 4, 5, 6}
>>> a
{1, 2, 5, 6}
>>> a = {1, 2, 3, 4}
>>> a.symmetric_difference_update({3, 4, 5, 6})
>>> a
{1, 2, 5, 6}

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

세트는 부분 집합, 진부분 집합, 상위 집합, 진상위 집합과 같이 속하는 관계를 표현할 수 있다. 현재 세트와 다른 세트의 (잔)부분 집합 또는 (진)상위 집합인지 확인할 때는 세트의 자료형에 부등호와 등호를 사용한다.

부분 집합 확인 ( <= )

현재 시트가 다른 시트의 부분 집합(subset)인지 확인하며 issubset 메서드와 같다. 등호가 있으므로 둘의 집합이 동일해도 참이다.

  • 현재세트 <= 다른세트
  • 현재세트.issubset(다른세트)
>>> a = {1, 2, 3, 4}
>>> a <= {1, 2, 3, 4}
True
>>> a.issubset({1, 2, 3, 4, 5})
True

Untitled

상위 집합 확인 ( < )

현재 세트가 다른 세트의 상위 집합(superset)인지 확인 issuperset 메서드와 동일.

등호가 있으므로 동일해도 참이다.

  • 현재세트 >= 다른세트
  • 현재세트.issuperset(다른세트)
>>> a = {1, 2, 3, 4}
>>> a >= {1, 2, 3, 4}
True
>>> a.issuperset({1, 2, 3, 4})
True

Untitled

진상위 집합 확인 ( > )

현재 시트가 다른 세트의 진상위 집합(proper superset)인지 확인하며 메서드는 없다.

둘 세트가 동일하면 거짓(False)이다.

  • 현재세트 > 다른세트
>>> a = {1, 2, 3, 4}
>>> a > {1, 2, 3}
True

Untitled

세트가 같은지 다른지 확인

같은지 확인 ( == )

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

다른지 확인 ( != )

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

세트가 겹치지 않는지 확인 ( isdisjoint )

  • 현재세트.isdisjoint(다른세트)
>>> a = {1, 2, 3, 4}
>>> a.isdisjoint({5, 6, 7, 8})       # 겹치는 요소가 없음
True
>>> a.isdisjoint({3, 4, 5, 6})    # a와 3, 4가 겹침
False

3. 세트 조작하기

요소 추가 (add)

>>> a = {1, 2, 3, 4}
>>> a.add(5)
>>> a
{1, 2, 3, 4, 5}

요소 삭제 (remove / discard)

>>> a.remove(3)
>>> a
{1, 2, 4, 5}
  • 요소를 삭제하고 해당 요소가 없으면 오류가 발생한다.
>>> a.discard(2)
>>> a
{1, 4, 5}
>>> a.discard(3)
>>> a
{1, 4, 5}
  • 요소를 삭제하고 해당 요소가 없으면 그냥 넘어간다.

임의의 요소 삭제 (pop)

>>> a = {1, 2, 3, 4}
>>> a.pop()
1
>>> a
{2, 3, 4}

임의의 요소를 삭제하고 해당 요소를 반환한다

모든 요소 삭제 (clear)

>>> a.clear()
>>> a
set()

요소 개수 구하기 (len)

>>> a = {1, 2, 3, 4}
>>> len(a)
4

4. 세트의 할당과 복사 ( copy )

세트도 딕셔너리나 리스트 처럼 할당과 복사의 차이점이 있다.

>>> a = {1, 2, 3, 4}
>>> b = a
>>> b.add(5)
>>> a
{1, 2, 3, 4, 5}
>>> b
{1, 2, 3, 4, 5}
>>> a is b
True

a = b 를 하여도 세트 두 개가 생성되는 것이 아니라 하나의 세트에 두 가지 이름이 할당된 것이다.

세트 a 와 b 를 완전히 두 개로 만드려고 하면 copy 메서드를 사용하면 된다.

>>> a = {1, 2, 3, 4}
>>> b = a.copy()
>>> a is b
False
>>> a == b
True
>>> a = {1, 2, 3, 4}
>>> b = a.copy()
>>> b.add(5)
>>> a
{1, 2, 3, 4}
>>> b
{1, 2, 3, 4, 5}

5. 세트 표현식

세트도 딕셔너리나 리스트 처럼 for 반복문과 if 조건문으로 세트를 생성할 수 있다.

  • {식 for 변수 in 반복가능한객체}
  • set(식 for 변수 in 반복가능한객체)
>>> a = {i for i in 'apple'}
>>> a
{'l', 'p', 'e', 'a'}

{ } 또는 set() 안에 식, 변수, in, 반복 가능한 객체를 지정하여 세트를 생성한다. 여기서 반복 가능한 객체로 "apple" 을 지정하였다.

Untitled

세트 표현식에 if 조건문

  • {식 for 변수 in 세트 if 조건식}
  • set(식 for 변수 in 세트 if 조건식)
>>> a = {i for i in 'pineapple' if i not in 'apl'}
>>> a
{'e', 'i', 'n'}

Untitled

profile
벨로그보단 티스토리를 사용합니다! https://flight-developer-stroy.tistory.com/

0개의 댓글