정점들과 그 사이를 연결하는 간선들이 주어졌을 때, 간선의 가중치가 모두 같다면 BFS(깊이우선탐색)를 활용하여 각 정점간의 최단거리를 구할 수 있다.  이번에는 간선들의 가중치가 서로 다를 때 최단거리를 구하기 위해 사용 가능한 알고리즘 중 하나인 Dijkstra의 알고리즘에 대해 정리해본다

 

 

 Dijkstra 알고리즘은 동적 계획법을 활용하여 최단경로를 구하는 알고리즘이다.  절차는 다음과 같다

 

① 먼저 시작점 s로부터의 각 정점까지의 거리를 나타낼 배열 d를 INF(무한)으로 초기화한다.

② d[s]를 0으로 초기화한다 (자기 자신과의 거리는 0이기 때문에)

③ 현 시점에서 가장 s로부터의 거리가 가까운 정점을 경유할 정점 m으로 잡고

    그 점을 경유한 최단거리로 d를 갱신한다. ( s -> m -> i == min(d[i], d[m] + graph[m][i]) )

④ ③을 더이상 갱신이 일어나지 않을 때 까지 반복한다.

 

실제 구현에 있어 주의해야할 부분은 두 가지가 있다. 그래프의 관리방식과 단계③에서 가장 가까운 경유점을 찾는 방식이다. 

 

그래프의 경우 단순히 n * n 배열로 관리하게될 경우 인접 정점을 찾기위해 매번 n-1회의 탐색이 필요하다(O(n)) 이를 해결하려면 그래프를 각 정점의 인접 정점들의 집합을 요소로 가지도록 하면 된다.

INF = float('inf')
g1 = [
    [0, 1, INF, 1],
    [1, 0, 1, INF],
    [INF, 1, 0, 1],
    [1, INF, 1, 0]
]

g2 = [
    [1, 3],
    [0, 2],
    [1, 3],
    [0, 2]
]

g1과 같이 그래프는 관리하는것 보다 g2와 같이 관리할 경우에 인접한 정점을 참조하기 위해 반복문을 보다 적게 돌릴 수 있다.

 

가까운 경유점을 찾는 방법의 경우 단순히 인접한 정점의 갯수만큼 반복문을 돌려 구할 수도 있지만

보다 빠르게 구하고자 한다면 경유할 점과 그 점까지의 거리를 우선순위 큐(힙)에 넣어 관리하면 시간복잡도를 O(logn)까지 줄일 수 있다. 큐에 들어있지만 이미 최단거리가 갱신돼버린 케이스의 존재를 감안해도 상당한 성능 향상을 기대할 수 있다. 

 

위 두가지 요소를 적용한 코드는 아래와 같다.

import sys
import heapq

input = sys.stdin.readline
INF = float('inf')


# 1753 최단경로
# 주어진 정점에서 시작하여 각 정점으로의 최단거리를 구하는 문제
# 다익스트라 알고리즘을 활용하여 해결 가능하다
def sol1753():
    # 정점의 갯수와 간선의 갯수
    v, e = map(int, input().split())

    # 시작점
    s = int(input())

    # 각 정점의 인접 정점과 그 사이의 거리
    g = [[] for _ in range(v + 1)]
    for _ in range(e):
        v1, v2, d = map(int, input().split())
        g[v1].append((v2, d))

    # 처음에는 모든 정점까지의 거리를 무한으로 초기화(자기 자신과의 거리는 0)
    dp = [INF] * (v + 1)
    dp[s] = 0

    # 경유하는 점의 시작으로 자기 자신을 집어넣음
    # 경유할 수 있는 점 중 가장 거리가 짧은 것을 우선적으로 방문하기 위해 우선순위 큐(heapq)를 사용한다
    q = [(0, s)]
    while q:
        distance, vertex = heapq.heappop(q)
        # 만약 경유할 정점까지의 거리가 최단거리가 아닐 경우 스킵
        if dp[vertex] < distance:
            continue
        # 시작점부터 경유할 정점까지의 거리 + 경유할 정점의 인접 정점까지의 거리로 시작점부터 인접 정점까지의 거리를 갱신
        # 갱신된 경우 해당 정점과 그 정점까지의 거리를 큐에 삽입
        for e, d in g[vertex]:
            c = dp[vertex] + d
            if c < dp[e]:
                dp[e] = c
                # 우선순위 기준을 거리로 잡기 위해 (거리, 정점번호) 의 형태로 큐에 삽입
                heapq.heappush(q, (c, e))
    print('\n'.join(map(conv, dp[1:])))


def conv(num):
    return 'INF' if num == INF else str(num)


if __name__ == '__main__':
	sol1753()

백준 온라인저지(Baekjoon Online Judge)의 1753번 문제(https://www.acmicpc.net/problem/1753)에 제출한 코드이다

 코딩테스트에서 자주 활용되는 알고리즘들을 조금씩 정리해두기로 한다

네트워크의 종단.  호스트와 브라우저 등의 애플리케이션이 여기에 속한다

 

1. Network Architecture

 ① 클라이언트-서버(Client-Server) 모델

  • 클라이언트(Client) : 네트워크를 통해 서버측에 접속하여 서비스를 요청하고 제공받는다.

  • 서버(Server) : 네트워크를 통해 클라이언트로부터 요청을 받아 서비스를 제공한다.
  • 서버가 다수의 클라이언트로부터 요청을 받아 이를 처리하고 결과를 반환하는 형태
  • 중앙 서버가 서비스와 데이터를 전적으로 관리하기 때문에 네트워크 구성 및 유지/보수가 효율적

  • 모든 부담이 중앙 서버에 집중되기 때문에 중앙 서버에 대한 공격을 허용하게 될 경우 치명적인
    상황으로 이어질 수 있다. 이를 막기위한 보안 솔루션이나 백업 등에 추가비용이 발생할 수 있다.

 

 ② P2P(Peer to Peer) 모델

  • 서비스를 제공하는 측과 요청하는 측이 비대칭적으로 존재하는 클라이언트-서버 모델과 달리
    연결된 모든 호스트가 서비스를 제공하는 측이면서 동시에 서비스를 요청하는 측이 되는 모델

  • 하나의 서버에 부담을 몰아주는 방식이 아니기 때문에 연결된 호스트가 늘어날 수록 트래픽과
    소모 자원을 분산시킬 수 있다는 장점이 있다.

  • 기능의 추가나 업데이트 관리가 어려우며 호스트간의 전송 속도 차이로 인해 정보 불일치나
    성능 저하 등의 문제가 발생할 수 있다.

 

 

2. Protocol

 ① 프로토콜(Protocol)

  • 네트워크에서의 Protocol이란 네트워크상에서의 통신을 위해 맺은 약속, 규약을 의미한다.

  • TCP, IP, UDP, HTTP, SMTP 등의 마지막 P는 모두 Protocol의 약자

 

 ② 연결지향(Connection Oriented) 서비스 - TCP(Transmission Control Protocol)

  • 서로 통신할 호스트간에 연결을 확립한 후 통신하는 방식. 네트워크 통신에 있어 여러 기능을 제공

  • reliable, in-order byte stream data transfer : 데이터의 순서유지, 데이터의 전달을 확인하고 유실시 재전송

  • flow control(흐름 제어) : 수신 측의 처리속도에 맞춰 데이터의 전송 속도(패킷의 전달 갯수) 조절

  • congestion control(혼잡 제어) : 네트워크망 내의 데이터의 전송 속도 조절을 통해 네트워크의 오버플로를 방지

 

 ③ 비연결지향(Connectionless) 서비스 - UDP(User Datagram Protocol)

  • 호스트간 연결을 확립하지 않고 통신하는 방식.  연결지향 서비스에서 제공하던 기능을 제공하지 않음

  • 흐름제어, 혼잡제어, 데이터의 신뢰성과 순서유지를 모두 지원하지 않음

  • 용도
    • 데이터의 유실이 치명적이지 않으며 실시간으로 빠르게 데이터를 전송할 필요가 있는 경우에 사용
    • broadcast 나 multicast 등 다수와의 통신이 이뤄질 경우 연결 확립이 불가능하기에 UDP가 사용됨
    • 화상회의 등이 대표적인 예시(음성과 영상의 실시간 전송)

'CS > 네트워크' 카테고리의 다른 글

#5 Application Layer 2 - HTTP  (0) 2021.11.01
#4 Socket Programming  (0) 2021.10.29
#3 Application Layer 1 - 소켓(Socket)  (0) 2021.10.28
#2 OSI 7계층  (0) 2021.10.28
#1 네트워크 구성 2 - Network Core  (0) 2021.10.28

1. 조건문 (if, elif, else)

# score>90 : A | score>80 : B | other : C

# score가 90보다 큰 경우
if score > 90:
	print('A')
    
# score가 90보다 크지는 않지만 80보다는 큰 경우
elif score > 80:
	print('B')
    
# 위 두 조건을 모두 만족하지 않는 경우
else:
	print('C')

 파이썬의 조건문 또한 다른 언어에서의 if else문과 거의 유사한 형태를 가진다.  else if 는 elif로 표기하며 이전

기본문법에도 설명했듯이 블록은 들여쓰기로 구분한다.  조건문 내의 명령문이 한 줄일 경우 : 뒤에 바로 명령문을

이어붙여 한줄로 처리하는 것도 가능하다.  조건문 자리에 숫자형 데이터가 올 경우 0은 False, 그 외에는 True

처리하며 문자열이나 리스트 등이 올 경우 비어있으면 False, 비어있지 않으면 True로 처리한다.

 

 파이썬에서 조건문 내부는 비워둘 수 없기 때문에 미구현 상태로 둘 경우 아무것도 하지 않고 넘어가는 pass 키워드

의도적으로 예외를 발생시키는 raise 키워드를 사용 가능하다.(미구현 상태임을 나타내기 위해)

 

 파이썬에는 switch문에 대응하는 문법은 존재하지 않기 때문에 조건문은 if문이 전부이며 굳이 switch문을 써야하는

상황일 경우 dictionary에 함수를 매핑하는 방식을 사용할 수는 있다.

 

2. 반복문 (while문, for문)

 - while 문

num = 0
while num<11:
	print(num)
    num += 1
    
#실행결과
0
1
2
3
4
5
6
7
8
9
10

 조건문이 참인 동안은 내부의 명령문을 반복수행한다.  다른 언어의 while문과 마찬가지로 break, continue 키워드를

사용 가능하며 do while문은 별도로 존재하지 않는다.  

 

 - for 문

# 일반적인 for문
nums = [1, 2, 3, 4, 5]
for num in nums:
	print(num, end=' ')	# 실행결과: 1 2 3 4 5
    
print()

# 언패킹을 활용한 for문
pairs = [(1, 5), (2, 4), (3, 3)]
for x, y in pairs:
	print(f'({x}, {y})', end=' ')	# 실행결과: (1, 5) (2, 4) (3, 3)

print()

# range를 활용한 for문
for i in range(10):
	print(i, end=' ')	# 실행결과: 0 1 2 3 4 5 6 7 8 9

 파이썬의 for문은 기본적으로 Java의 enhanced for와 같은 구조로 돼어있다.  for <var> in <iterable>의 형태로

iterable한 자료구조 내부의 데이터들을 순차적으로 참조하는 방식이다.  또한 참조할 데이터가 튜플이나 리스트 등의

형태일 경우 여러개의 변수에 언패킹하여 참조하는 것도 가능하다. 

 

 다른 언어에서 사용하던 인덱스 방식의 for문을 사용하고 싶을 경우 range와 함께 사용 가능하다. range는 유한한 구간 내의 정수들의 집합을 나타내는 자료구조이다.  range에 대한 자세한 내용은 이후 별도로 포스팅하기로 한다.

'언어 > Python' 카테고리의 다른 글

#12 json 모듈  (0) 2021.09.23
#10 특수한 매개변수  (0) 2021.05.26
#9 입력을 받는 여러 방법  (0) 2021.04.06
#8 우선순위 큐(heapq)  (0) 2021.04.05
#7 데크(deque)  (0) 2021.04.05

  Python에서 함수를 선언할 때 이름 앞에 * 또는 **이 붙은 특수한 형태의 매개변수를 사용 가능하다.  

 

 1.  *매개변수 (가변 개수 매개변수)

def func1(*args):
	print(args)
   

def func2(num, *args):
	print(num, args)
  
   
func1(1, 2, 3, 4)	# 실행결과: (1, 2, 3, 4)
func2(1, 2, 3, 4)	# 실행결과: 1 (2, 3, 4)

 매개변수명 앞에 *을 붙일 경우 매개변수들을 튜플의 형태로 묶어 전달받게된다.  이러한 형태의 매개변수는 하나만

사용 가능하며(두 개 이상 사용될 경우 서로 구분이 불가능) 일반적인 매개변수와 함께 사용 가능하다. 이 경우 일반

변수는 호출 시에 변수이름을 명시하거나 가변 개수 매개변수보다 먼저 입력받도록 선언해야한다.

 

 

2. **매개변수 (키워드 매개변수)

def func1(**args):
	print(args)


def func2(num, **args):
	print(num, args)
   
   
func1(a=2)		# 실행결과: {'a': 2}
func2(3, a=3)		# 실행결과: 3 {'a': 3}

 매개변수명 앞에 **을 붙일 경우 key=value형태의 매개변수를 dictionary 타입으로 저장한다.  일반 매개변수나

가변 개수 매개변수와 혼용할 경우 반드시 마지막으로 입력받도록 선언해야한다. 

'언어 > Python' 카테고리의 다른 글

#12 json 모듈  (0) 2021.09.23
#11 흐름제어 (조건문, 반복문)  (0) 2021.05.27
#9 입력을 받는 여러 방법  (0) 2021.04.06
#8 우선순위 큐(heapq)  (0) 2021.04.05
#7 데크(deque)  (0) 2021.04.05

 파이썬에서 값을 입력받는 다양한 방법에 대해 알아본다

 

1. input()

print(input())	# 결과: 마지막 개행문자를 제외한 라인 전체

 input()은 파이썬에서 사용자 입력을 받기 위한 가장 기본적인 함수이다.  기본적으로 line 단위로 입력을 받는 함수이며

입력받은 내용을 마지막의 개행문자를 제거한 문자열의 형태로 반환한다.  EOF를 읽을 경우 EOFError를 발생시킨다.

인자로 문자열을 넘겨줄 경우 개행없이 출력해준다.(prompt)

 

 

2. sys.stdin.readline()

import sys
input = sys.stdin.readline()
print(input())	# 결과: 마지막의 개행문자를 포함한 라인 전체

 sys.stdin.readline()은 input()과 마찬가지로 사용자 입력을 line 단위로 받을 수 있는 함수이다.  input()과 다른 점은

마지막 개행문자를 제거해주지 않으며 prompt 매개변수를 받지 않는다는것, 그리고 EOF를 만났을때 EOFError를 

발생시키지 않고 빈 문자열을 반환한다는 점이다.  

 

 많은 양의 입력을 처리해야 할 때 sys.stdin에 정의된 함수들은 사용자 입력을 받아오기 위한 버퍼를 생성하여

입력을 처리하기에 내장함수 input을 사용하는 것 보다 매우 빠른 속도를 보인다.

 

3. sys.stdin.readlines()

import sys
input = sys.stdin.read()
s = input()

 sys.stdin.readlines()는 입력을 line 단위로 끊어 리스트의 형태로 반환하는 함수이다.  readline 함수를 여러번 호출하여 리스트에 집어넣은 것과 같다. 

 

4. sys.stdin.read()

import sys
input = sys.stdin.read()
s = input()

 sys.stdin.read()는 EOF를 만나기 전까지 모든 입력을 하나의 문자열로 반환하는 함수이다.  

 

'언어 > Python' 카테고리의 다른 글

#11 흐름제어 (조건문, 반복문)  (0) 2021.05.27
#10 특수한 매개변수  (0) 2021.05.26
#8 우선순위 큐(heapq)  (0) 2021.04.05
#7 데크(deque)  (0) 2021.04.05
#6 재귀 제한(recursion limit)  (0) 2021.04.05

 힙(heap)은 느슨한 정렬상태를 유지하여 루트 노드에 항상 최대, 혹은 최소값이 오도록 하는 트리형

자료구조이다. 이 구조를 활용하여 삽입된 데이터중 보다 우선순위가 높은 것을 먼저 반환하는

우선순위 큐를 구현할 수 있다.

파이썬에서는 heapq 모듈에 정의된 함수를 사용하여 리스트를 우선순위 큐로 사용한다.

 

import heapq

q = []

heapq.heappush(q, 3)
heapq.heappush(q, 1)
heapq.heappush(q, 8)

for _ in range(len(q)):
 print(heapq.heappop(q), end=' ') # 결과: 1 3 8

 위 코드와 같이 heappush() , heappop() 함수를 통해 힙을 유지하며 삽입하고 최소값을 우선적으로 반환받을 수 있다.

heapq는 기본적으로 최소 힙이며 최대 힙을 구현하고싶을 경우 키 값을 음수형태로 취하는 방식을 사용할 수 있다.

 

heappop()은 O(1)의 시간복잡도를, heappush()는 O(logN)의 시간 힙(heap)은 느슨한 정렬상태를 유지하여 루트 노드에 항상 최대, 혹은 최소값이 오도록 하는 트리형 자료구조이다.

이 구조를 활용하여 삽입된 데이터중 보다 우선순위가 높은 것을 먼저 반환하는 우선순위 큐를 구현 가능하다.

파이썬에서는 heapq 모듈에 정의된 함수를 사용하여 리스트를 우선순위 큐로 사용할 수 있다.

 

import heapq

q = []
heapq.heappush(q, 3)
heapq.heappush(q, 1)
heapq.heappush(q, 8)
for _ in range(len(q)):
	print(heapq.heappop(q), end=' ') # 결과: 1 3 8

 위 코드와 같이 heappush() , heappop() 함수를 통해 힙을 유지하며 삽입하고 최소값을 우선적으로 반환받을 수 있다.

heapq는 기본적으로 최소 힙이며 최대 힙을 구현하고싶을 경우 키 값을 음수형태로 취하는 방식을 사용할 수 있다.

heappop()은 O(1)의 시간복잡도를, heappush()는 O(logN)의 시간복잡도를 가진다.

 

값의 삭제 없이 최소값을 확인만 하고싶은 경우 단순히 인덱스 0 을 참조하면 된다.

 

기존에 값이 들어있는 리스트를 힙으로 사용하려면 heapq.heapify(<리스트>) 함수를 사용할 수 있다.

heapify() 함수는 리스트의 요소들을 하나하나 heappush()한 것과 같은 결과를 내며 O(N)의 시간복잡도를 가진다.

'언어 > Python' 카테고리의 다른 글

#10 특수한 매개변수  (0) 2021.05.26
#9 입력을 받는 여러 방법  (0) 2021.04.06
#7 데크(deque)  (0) 2021.04.05
#6 재귀 제한(recursion limit)  (0) 2021.04.05
#5 집합(Set)  (0) 2021.03.02

 데크(deque)는 큐(queue)의 일종으로 양 방향에서 삽입/삭제가 가능한 선형자료구조이다.

파이썬에서는 collections 모듈에 정의된 데크를 사용 가능하다.

 

from collections import deque

q = deque()

q.append(3)
print(q)	# 결과: deq([3])

q.appendleft(4)
print(q)	# 결과: deque([4, 3])

print(q.popleft())
print(q)	# 결과: deque([3])

 위 코드와 같이 기존 리스트에서 사용 가능했던 append(), pop()에 더해 좌측 끝에서 삽입/삭제를 수행하는

appendleft(), popleft() 함수를 사용 가능하다.  이 두 함수는 O(1)의 시간복잡도를 가지기에 기존 리스트에서

insert()와 del 을 사용한 좌측 끝의 삽입 삭제보다 효율적이다.

'언어 > Python' 카테고리의 다른 글

#9 입력을 받는 여러 방법  (0) 2021.04.06
#8 우선순위 큐(heapq)  (0) 2021.04.05
#6 재귀 제한(recursion limit)  (0) 2021.04.05
#5 집합(Set)  (0) 2021.03.02
#4 딕셔너리(Dictionary)  (0) 2021.02.25

 파이썬은 함수의 재귀호출 횟수가 기본 1000회로 제한되어있다.  기본 횟수 이상으로 재귀호출을 해야할 경우

제한 횟수를 다시 설정해줘야한다.

import sys

# 현재 재귀 제한 횟수를 가져옴
limit = sys.getrecursionlimit()
print(limit)	# 결과: 1000

# 재귀 제한 횟수를 재설정
sys.setrecursionlimit(1500)

# 변경된 재귀 제한 횟수를 가져옴
limit = sys.getrecursionlimit()
print(limit)	# 결과: 1500

 위 코드와 같이 sys.getrecursionlimit() 함수를 호출하여 현재 재귀호출 횟수 제한 값을 가져오고

sys.setrecursionlimit() 함수를 호출하여 횟수 제한을 재설정 할 수 있다.

 

 

'언어 > Python' 카테고리의 다른 글

#8 우선순위 큐(heapq)  (0) 2021.04.05
#7 데크(deque)  (0) 2021.04.05
#5 집합(Set)  (0) 2021.03.02
#4 딕셔너리(Dictionary)  (0) 2021.02.25
#3 튜플(Tuple)  (0) 2021.02.24

 집합(Set)은 순서가 없고(non-sequence) 변경 가능(mutable)하며 중복을 허용하지 않는 자료구조이다.

집합의 원소로 다양한 타입의 데이터가 사용될 수 있지만 mutable한 데이터는 사용 불가능하다. 

주로 멤버십(집합과 원소의 포함 관계) 검사데이터의 중복의 제거, 합집합, 교집합, 차집합 등의 집합 간 연산을 활용하기 위한 용도로 사용된다.

 

선언

my_set1 = {1, 2, 3, 4, 5}
my_set2 = set([1, 2, 3])
my_set3 = set('hello')
print(my_set1)	# 실행결과: {1, 2, 3, 4, 5}
print(my_set2)	# 실행결과: {1, 2, 3}
print(my_set3)	# 실행결과: {'l', 'h', 'o', 'e'}

 집합의 선언은 중괄호 안에 직접 원소를 명시하는 방식과 set 메소드를 호출하는 방식이 있다.

set 메소드의 인자로는 iterable한 인스턴스가 올 수 있으며 집합이 생성되는 과정에서 중복은 제거되며
순서는 유지되지 않는다.  이러한 성질을 활용하여 중복 데이터를 제거하기 위해 집합을 활용하기도 한다.

 

삽입

1. add 메소드

my_set = {1, 2, 3, 4, 5}
my_set.add(6)
print(my_set)	# 실행결과: {1, 2, 3, 4, 5, 6}

  집합에 하나의 값을 추가한다. 

 

2. update 메소드

my_set = {1, 2, 3, 4, 5}
my_set.update([5, 6, 7])
print(my_set)	# 실행결과: {1, 2, 3, 4, 5, 6, 7}

  집합에 여러개의 값을 추가한다.  이 과정에서 중복데이터는 제거된다.

 

삭제

1. remove 메소드

my_set = {1, 2, 3, 4, 5}
my_set.remove(3)
print(my_set)		# 실행결과: {1, 2, 4, 5}

my_set.remove(3)	# 실행결과: KeyError 발생

 인자로 넘겨준 값을 삭제한다.  제거하려는 데이터가 존재하지 않는 경우 KeyError를 발생시킨다

 

2. discard 메소드

my_set = {1, 2, 3, 4, 5}
my_set.discard(3)
print(my_set)		# 실행결과: {1, 2, 4, 5}
my_set.discard(3)
print(my_set)		# 실행결과: {1, 2, 4, 5}

 remove와 동일하게 인자로 넘겨준 값을 삭제한다.  remove와 달리 제거하려는 데이터가 존재하지 않아도 에러를

발생시키지 않는다.

 

집합연산

my_set1 = {1, 2, 3, 4, 5}
my_set2 = {4, 5, 6, 7, 8}

# 합집합
uni_set1 = my_set1 | my_set2
uni_set2 = my_set1.union(my_set2)
print(uni_set1)		# 실행결과: {1, 2, 3, 4, 5, 6, 7, 8}
print(uni_set2)		# 실행결과: {1, 2, 3, 4, 5, 6, 7, 8}

# 차집합
dif_set1 = my_set1 - my_set2
dif_set2 = my_set1.difference(my_set2)
print(dif_set1)		# 실행결과: {1, 2, 3}
print(dif_set2)		# 실행결과: {1, 2, 3}

# 교집합
int_set1 = my_set1 & my_set2
int_set2 = my_set1.intersection(my_set2)
print(int_set1)		# 실행결과: {4, 5}
print(int_set2)		# 실행결과: {4, 5}

# 대칭차집합 (합집합 - 교집합)
sym_set1 = my_set1 ^ my_set2
sym_set2 = my_set1.symmetric_difference(my_set2)
print(sym_set1)		# 실행결과: {1, 2, 3, 6, 7, 8}
print(sym_set2)		# 실행결과: {1, 2, 3, 6, 7, 8}

 집합 연산에는 연산자를 사용한 방식과 연산을 위한 set의 내장메소드를 사용하는 방법이 있다.

합집합 연산 : 연산자 | 또는 내장메소드 union

차집합 연산 : 연산자 - 또는 내장메소드 difference

교집합 연산 : 연산자 & 또는 내장메소드 intersection

대칭차집합 연산 : 연산자 ^ 또는 내장메소드 symmetric_difference

 

포함관계

my_set1 = {1, 2, 3, 4, 5}
my_set2 = {3, 4, 5}
my_set3 = {6, 7, 8}

# 부분집합 여부 (a.issubset(b) : a가 b의 부분집합일 경우 True, 아닐경우 False)
print(my_set1.issubset(my_set2))	# 실행결과: False
print(my_set2.issubset(my_set1))	# 실행결과: True

# 상위집합 여부 (a.issuperset(b) : a가 b를 포함할 경우 True, 아닐경우 False)
print(my_set2.issuperset(my_set1))	# 실행결과: False
print(my_set1.issuperset(my_set2))	# 실행결과: True

# 교집합 유무 (a.isdisjoint(b) : a와 b의 교집합이 없을 경우 True, 아닐경우 False)
print(my_set1.isdisjoint(my_set2))	# 실행결과: False
print(my_set1.isdisjoint(my_set3))	# 실행결과: True

 집합간의 포함관계를 확인하기 위한 내장 메소드로 issubset, issuperset, isdisjoint 가 있다.

 

 복사의 경우 다른 자료구조들과 마찬가지로 내장된 copy메소드를 호출하여 얕은 복사본을 만들 수 있다.

집합의 경우 그 원소로 immutable한 값만이 올 수 있기에 깊은복사는 의미가 없다.

'언어 > Python' 카테고리의 다른 글

#7 데크(deque)  (0) 2021.04.05
#6 재귀 제한(recursion limit)  (0) 2021.04.05
#4 딕셔너리(Dictionary)  (0) 2021.02.25
#3 튜플(Tuple)  (0) 2021.02.24
#2 리스트(List)  (0) 2021.02.24

+ Recent posts