본문 바로가기
BASIC

set

by 자동매매 2023. 11. 27.
메서드 집합 연산자 설명
set.union(세트1, 세트2) | 두 세트의 합집합
set.intersection(세트1, 세트2) & 두 세트의 교집합
set.difference(세트1, 세트2) - 두 세트의 차집합
set.symmetric_difference(세트1, 세트2) ^ 두 세트의 대칭차집합
update(다른세트) |= 현재 세트에 다른 세트를 더함
intersection_update(다른세트) &= 현재 세트와 다른 세트 중에서 겹치는 요소만 현재 세트에 저장
difference_update(다른세트) -= 현재 세트에서 다른 세트를 뺌
symmetric_difference_update(다른세트) ^= 현재 세트와 다른 세트 중에서 겹치지 않는 요소만 현재 세트에 저장
issubset(다른세트) <= 현재 세트가 다른 세트의 부분집합인지 확인
  현재 세트가 다른 세트의 진부분집합인지 확인
issuperset(다른세트) >= 현재 세트가 다른 세트의 상위집합인지 확인
  현재 세트가 다른 세트의 진상위집합인지 확인
isdisjoint(다른세트)   현재 세트가 다른 세트와 겹치지 않는지 확인
add(요소)   세트에 요소를 추가
remove(요소)   세트에서 특정 요소를 삭제, 없으면 에러 발생
discard(요소)   세트에서 특정 요소를 삭제, 요소가 없으면 그냥 넘어감
pop()   세트에서 임의의 요소를 삭제하고 해당 요소를 반환
clear()   세트에서 모든 요소를 삭제
copy()   세트를 복사하여 새로운 세트 생성

1. 세트 만들기

파이썬은 집합을 표현하는 세트(set)라는 자료형을 제공합니다. 집합을 영어로 하면 세트인데 수학에서 배우는 그 집합이 맞습니다. 따라서 세트는 합집합, 교집합, 차집합 등의 연산이 가능합니다.

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

간단하게 과일이 들어있는 세트를 만들어보겠습니다.

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

 

세트는 요소의 순서가 정해져 있지 않습니다(unordered).

세트에 들어가는 요소는 중복될 수 없습니다. 

 

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

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

 

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

  • set(반복가능한객체)
>>> a = set('apple')    # 유일한 문자만 세트로 만듦
>>> a
{'e', 'l', 'a', 'p'}
>>> b = set(range(5))
>>> b
{0, 1, 2, 3, 4}
>>> c = set()
>>> c
set()

 

c = {}와 같이 만들면 빈 딕셔너리가 만들어지므로 주의해야 합니다. 

  • type(객체)
>>> c = {}
>>> type(c)
<class 'dict'>
>>> c = set()
>>> type(c)
<class 'set'>
 
 
한글 문자열을 세트로 만들기

set을 사용하여 한글 문자열을 세트로 만들면 다음과 같이 음절 단위로 세트가 만들어집니다.

>>> set('안녕하세요')
{'녕', '요', '안', '세', '하'}
 
 
세트 안에 세트 넣기 불가   => frozenset은 가능

 

>>> 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'
 
 
프로즌 세트

파이썬은 내용을 변경할 수 없는 세트도 제공합니다.

프로즌세트 = frozenset(반복가능한객체)

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

 

요소를 추가하거나 삭제하는 연산, 메서드는 사용할 수 없습니다. 

>>> 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만 넣을 수 있고, 일반 set는 넣을 수 없습니다.

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

 


2. 집합 연산 사용하기

1) 합집합

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

 

2) 교집합(intersection)

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

3) 차집합(difference)

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

 

4) 대칭차집합(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}

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

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

 

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

 

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

 

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

 

 

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

 

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

 

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

 

  • 현재세트 > 다른세트          : 진상위집합
>>> a = {1, 2, 3, 4}
>>> a > {1, 2, 3}
True

 

5. 세트가 같은지 다른지 확인하기  : ==, != 연산자 사용

>>> 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

 

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

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

 

7. 세트에서 요소 추가하기

add(요소)는 세트에 요소를 추가합니다.

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

 

8. 세트에서 특정 요소를 삭제하기

remove(요소)는 세트에서 특정 요소를 삭제하고 요소가 없으면 에러를 발생시킵니다.

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

 

discard(요소)는 세트에서 특정 요소를 삭제하고 요소가 없으면 그냥 넘어갑니다. 

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

 

9. 세트에서 임의의 요소 삭제하기

pop()은 세트에서 임의의 요소를 삭제하고 해당 요소를 반환합니다. 만약 요소가 없으면 에러를 발생시킵니다.

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

 

10. 세트의 모든 요소를 삭제하기

clear()는 세트에서 모든 요소를 삭제합니다.

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

 

11. 세트의 요소 개수 구하기

len(세트)는 세트의 요소 개수(길이)를 구합니다.

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

 

12. 세트의 할당과 복사

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

 

 

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

 

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

for 변수 in 세트:
     반복할 코드

 

>>> a = {1, 2, 3, 4}
>>> for i in a:
...     print(i)
...
1
2
3
4

 

14. 세트 표현식 사용하기

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

 

세트 표현식에 if 조건문 사용하기

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

 

 

## 딕셔너리와 세트는 while로 반복할 수 있나요?

딕셔너리와 세트를 while로 반복하려면 조금 복잡합니다.

다음과 같이 딕셔너리와 세트에서 이터레이터를 얻은 뒤에 next로 요소를 차례대로 꺼내면 됩니다.

x = {"a": 10, "b": 20, "c": 30, "d": 40, "e": 50}                 # 딕셔너리
# x = {'strawberry', 'grape', 'orange', 'pineapple', 'cherry'}    # 세트
it = iter(x)                   # 이터레이터를 얻음
while True:
    try:
        print(x[next(it)])     # 딕셔너리에 키를 지정해서 값 출력
        # print(next(it))      # 세트의 요소 출력
    except StopIteration:
        break

 

 

[ 연습문제 ]

다음 소스 코드를 완성하여 1부터 100까지 숫자 중 3과 5의 공배수를 세트 형태로 출력되게 만드세요.

a = {i for i in range(1, 101) if i % 3 == 0}                                          
b = {i for i in range(1, 101) if i % 5 == 0}                                   
 
print(a & b)

 

 

표준 입력으로 양의 정수 두 개가 입력됩니다. 
다음 소스 코드를 완성하여 두 숫자의 공약수를 세트 형태로 구하도록 만드세요. 
단, 최종 결과는 공약수의 합으로 판단합니다.

a, b = map(int, input().split())
a = {i for i in range(1, a + 1) if a % i == 0}
b = {j for j in range(1, b + 1) if b % j == 0}

divisor = a & b

result = 0
if type(divisor) == set:
    result = sum(divisor)

print(result)
입력
10 20
결과
18
입력
100 200
결과
217

'BASIC' 카테고리의 다른 글

회문 판별과 N-gram 만들기  (1) 2023.11.28
파일 다루기  (2) 2023.11.28
딕셔너리 응용하기  (1) 2023.11.27
문자열 포매팅  (1) 2023.11.25
문자열 method  (1) 2023.11.25

댓글