: itertools, heapq, bisect, collections, math
라이브러리 | 설명 |
---|---|
내장 함수 | 기본 입출력 기능부터 정렬 기능(sorted())을 포함하고 있는 기본 내장 라이브러리 |
itertools | 반복되는 형태의 데이터 처리하는 기능을 제공하는 라이브러리 순열과 조합 라이브러리 제공 |
heapq | 우선순위 큐 구현에 사용 |
bisect | 이진 탐색 기능 제공 |
collections | deque, Counter 등의 자료구조 포함하는 라이브러리 |
math | 필수적인 수학적 기능 제공 |
result = eval("(3 + 5) * 7)
print(result)
result = sorted(iterable 객체, key=lambda x: x[2], reverse = True)
from itertools import ___
iterable 객체에서 r개의 데이터를 뽑아 일렬로 나열하는 모든 경우를 계산
permutations는 클래스이기 때문에, 객체 초기화 이후에는 리스트로 변환해서 사용
from itertools import permutations
array = ['a', 'b', 'c']
result = list(permutations(array, r))
# [('a', 'b'), ('a', 'c'), ('b', 'a'), (’b’, ‘c’), (’c’, ‘a’), (’c’, ‘b’)]
iterable 객체에서 r개의 데이터를 뽑아 순서를 고려하지 않고 나열하는 모든 경우를 계산
from itertools import combinations
array = ['a', 'b', 'c']
result = list(combinations(array, r))
# [('a', 'b'), ('a', 'c'), ('b', 'c')]
permutations 복원추출 ver.
from itertools import product
array = ['a', 'b', 'c']
result = list(product(array, repeat = 2))
# 생략 ( 3^2 개 생성 )
repeat 속성: 중복 허용
repeat을 써주지 않으면 TypeError: 'int' object is not iterable 발생
combinations 복원 추출 ver.
from itertools import combinations_with_replacement
array = ['a', 'b', 'c']
result = list(combinations_with_replacement(array, 2))
# [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
힙 기능을 위한 표준 라이브러리
다익스트라 최단 경로 알고리즘 등 우선 순위 큐 기능을 구현할 때 사용
코딩테스트 환경에서는 heapq가 PriorityQueue 라이브러리보다 빠르게 작동
import heapq
heap = [] # 빈 리스트를 사용
heapq.heappush(heap, value) # 원소 삽입
heapq.heappop(heap) # 원소 삭제
len(heap)
O(NlogN)
heapq.heappush(heap, value)
heapq.heappop(heap)
하면 힙의 루트 원소, 즉 최솟값이 pop됨def heapsort(iterable):
heap = []
result = []
for value in iterable:
heapq.heappush(heap, value) # 모든 원소 힙에 넣고
for i in range(len(heap)):
result.append(heapq.heappop(heap)) # 차례로 꺼내서 결과 저장
return result
def heapsort(iterable):
heap = []
result = []
for value in iterable:
heapq.heappush(heap, **-value**)
for i in range(len(heap)):
result.append(**-heapq.heappop(heap)**)
return result
N = int(sys.stdin.readline()) * -1
heap[0]
heap[1]
이나 heap[2]
그 다음으로 작은 수가 있다고 보장할 수 없음heappop()
함수로 원소 삭제할 때마다 이진 트리 재배치 → 새로운 최솟값을 인덱스 0에 위치시키는 것!heappop()
으로heap[0]
을 제거한 뒤에 다시 heap[0]
에 접근해야 함heapq
모듈의 heapify()
함수 사용heapify()
로 리스트 넘기면, 리스트 내부 원소들이 힙 구조에 맞게 재배치 → 최솟값이 0번째 인덱스에 위치됨heappush()
로 원소 하나씩 추가한 효과 O(N)
의 시간 복잡도import heapq
heap = [4, 5, 1, 2]
heapq.heapify(heap)
# [1, 2, 4, 5]
heapq
모듈로 구현되어 있음put
, get
함수 ⇒ O(logN)
from queue import PriorityQueue
queue = PriorityQueue() # default size는 무한대, maxsize 인자로 사이즈 지정 가능
queue.put(value) # 원소 삽입
queue.get() # 원소 제거
# [1, 2, 4, 5]
(우선순위, 값)
의 튜플 형태로 데이터 추가 및 제거queue.put((3, 'A'))
queue.put((1, 'B'))
queue.put((2, 'C'))
print(queue.get()[1]) # B
print(queue.get()[1]) # C
print(queue.get()[1]) # A
이진 탐색(Binary Search) 기능을 제공하는 표준 라이브러리
bisect_left(a, x)
: 정렬된 순서를 유지하면서, 리스트 a에 데이터 x를 삽입할 가장 왼쪽 인덱스 찾기
bisect_right(a, x)
: 정렬된 순서를 유지하도록 리스트 a에 데이터 x를 삽입할 가장 왼쪽 인덱스 찾기
⇒ 시간 복잡도O(logN)
from bisect import bisect_left, bisect_right
def count_by_range(a, left_value, right_value):
right_idx = bisect_right(a, right_value)
left_idx = bisect_left(a, left_value)
return right_idx - left_idx
a = [1, 2, 3, 3, 3, 5, 5, 7]
print(count_by_range(a, 3, 3)) # 3의 개수 -> 3
deque, Counter 등 유용한 자료구조를 제공하는 표준 라이브러리
from collections import deque
a = deque([1, 2, 3, .. ])
pop()
: 마지막 원소를 제거한 뒤 반환popleft()
: 첫 번째 원소를 제거한 뒤 반환append(x)
: deque 오른쪽에 x 삽입appendleft(x)
: deque 왼쪽에 x 삽입clear()
: deque의 모든 원소를 제거copy()
: deque의 shallow copy를 생성count(x)
: x와 같은 deque element의 수 계산rotate(r)
: r만큼 회전, r이 음수이면 좌측으로 회전len(deq)
: 덱의 길이max(deq)
: 덱의 최댓값
추가: deque.rotate()
deq = deque([1, 2, 3, 4, 5])
deq.rotate(1) # deque([5, 1, 2, 3, 4])
deq.rotate(-1) # deque([1, 2, 3, 4, 5])
deq.rotate(-1) # deque([2, 3, 4])
추가: 덱끼리의 연결
append
vs extend
vs +
d1 = deque([5, 6, 7, 8]) d2 = deque([1, 2, 3, 4])
d1.appendleft(d2)
# deque([deque([1, 2, 3, 4]), 5, 6, 7, 8])
d1.extend(d2)
# deque([5, 6, 7, 8, 1, 2, 3, 4])
d1.extendleft(d2)
# deque([4, 3, 2, 1, 5, 6, 7, 8])
d2 = deque([1, 2, 3, 4])
# deque([1, 2, 3, 4, 5, 6, 7, 8])
deque에다가 deque을 append()
하면 deque() object 자체가 들어감
연결하고 싶을 때는 extend()
또는 +
를 쓸 수 있는데,
extend()
를 쓰면 d1.extendleft(d2)
에서 d2의 첫 원소부터 차례로 d1의 왼쪽에 들어가게 되므로 d2의 순서가 뒤바뀐 채 들어감
두 deque을 단순 연결하고 싶으면, 앞에 올 deque + 뒤에 올 deque
을 사용하면 됨
from collections import Counter
counter = Counter(['a', 'b', 'a', 'c', 'b', 'b', 'a', 'b'])
print(counter) # Counter({'b': 4, 'a': 3, 'c': 1})
print(dict(counter) # {'b': 4, 'a': 3, 'c': 1}
자주 사용되는 수학적인 기능을 포함하고 있는 표준 라이브러리
math.factorial(x)
: x! 반환math.sqrt(x)
: 제곱근 반환math.gcd(a, b)
: 최대 공약수 반환