파이썬으로 알고리즘을 풀어보면서 자주 찾아보게 되었던 내용을 정리합니다.
readline
사용하기input()
은 시간 초과의 주범입니다. readline
을 input
처럼 사용하면 입력을 읽는 데 걸리는 시간을 줄일 수 있습니다.import sys
input = sys.stdin.readline
strip()
처리를 해주지 않으면 빈 문자열도 배열에 담깁니다.arr = input().strip().split()
arr = list(map(int, input().split()))
n = int(input()) # n개의 행으로 이루어진 경우
arr = [input().strip().split() for _ in range(n)]
# readline()을 input()으로 사용
while True:
s = sys.stdin.readline().rstrip('\n')
if not s:
break
# 혹은, 기본 input() 사용
while True:
try:
a, b = input().split()
print(a + b)
except:
break
dic = {"name": "value", "key_one": 2}
dic["hi"] = 123
print(dic["hi"]) # 123
list(s)
"".join(arr)
""
자리에 " ", ","
등의 문자(열)를 넣어서 구분자를 설정할 수 있습니다.''.join(map(str, a))
join
은 string 값이나 배열에 대해서만 수행 가능하므로 map 처리를 해줍니다.remove
, insert
메소드 지양하기 - 시간복잡도가 O(N)인 연산이므로 자주 사용하면 시간 초과됩니다!!set()
으로 감싸서 set으로 만들기zip()
weight = [200, 300, 100]
value = [22, 66, 42]
for w, v in zip(weight, value):
print(w, v)
# (200 22), (300 66), (100 42) 순서로 출력됨
from collections import deque
queue = deque()
queue.append(2) # 요소 추가
queue.popleft() # 가장 처음에 들어간 요소를 빼내기
import heapq
heap = []
heapq.heappush(heap, 3) # 요소 넣기
heapq.heappop(heap) # 가장 우선순위 높은 요소 빼내기
(우선순위, 실제 값)
튜플 형태로 넣어주면 됩니다.arr.sort()
⇒ arr 자체가 정렬됨sorted(arr)
⇒ arr은 정렬되지 않고, 정렬된 새 배열을 반환함arr = [(5, 1), (88, 4), (77, 1), (4, 3)]
arr.sort(key=lambda x: (x[1], -x[0]))
# arr ⇒ [(77, 1), (5, 1), (4, 3), (88, 4)]
# > 1번 인덱스 요소를 오름차순으로 정렬하고,
# > 1번 인덱스 요소가 같을 때는 0번 인덱스 요소의 내림차순으로 정렬
bisect_left
기존 요소의 가장 왼쪽 값 인덱스, bisect_right
는 기존 요소의 가장 오른쪽 값의 다음 인덱스를 반환합니다.from bisect import bisect_left, bisect_right
arr = [2,5,5,5,7,9]
print(bisect_left(arr, 2)) # 0
print(bisect_left(arr, 5)) # 1
print(bisect_right(arr, 5)) # 4
print(bisect_right(arr, 9)) # 6
count = bisect_right(arr, 5) - bisect_left(arr, 5)
# count == 3
ord(c)
c.isalpha() # 문자로만 되어 있는가? (대문자 or 소문자 or 한글 등의 문자만 인정, 공백이나 특수문자 인정하지 않음)
c.isalnum() # 문자 혹은 숫자로만 되어 있는가? (공백이나 특수문자 인정하지 않음)
c.isdigit() # 숫자로 되어 있는가? (거듭제곱 등의 기호까지 인정)
c.numeric() # 숫자처럼 생긴 글자인가? (제곱근, 분수, 거듭제곱까지 인정)
c.islower() # 소문자로만 이루어져 있는가?
c.isupper() # 대문자로만 이루어져 있는가?
new_lower = c.lower() # c를 소문자로 변경하여 반환, c는 바뀌지 않음
new_upper = c.upper() # c를 대문자로 변경하여 반환, c는 바뀌지 않음
s.strip()
"{0.nf}".format(a)
# 올림
math.ceil(a)
# 내림 / 음수일 경우 절대값 취하고 +1 (0에서 멀어짐)
math.floor(a)
# 내림 / 음수일 경우 절대값 취하고 -1 (0에 가까워짐)
math.trunc(a)
# 반올림
math.round(a)
def sum_digit(n):
if n < 10:
return n;
return (n % 10) + sum_digit(n // 10)
def sum_digit(n):
return sum(map(int, str(n)))
N까지의 모든 정수가 각각 소수인지 아닌지 여부를 알고 싶을 때
for 문을 도는 횟수를 줄이기 위해서 3번의 경우 n의 제곱근보다 약간 큰 수까지만 확인합니다.
arr = [True] * (n + 1)
arr[0] = False
arr[1] = False
for i in range(2, int(n ** 0.6)):
if arr[i] == True:
j = 2
while (i * j) <= n:
arr[i * j] = False
j += 1
# arr에서 True 값을 가지고 있는 index는 소수입니다.
f = [1] * 1001
for i in range(2, x):
f[i] = f[i - 1] * i
GCD(a, b) == GCD(b, r)
def gcd(a, b):
if b > a:
gcd(b, a)
if b == 0:
return a
return gcd(b, a % b)
lcm = a * b / GCD(a, b)
import itertools
# 순열
itertools.permutations(arr, r)
# n개 중에 r개를 나열하는 경우의 수 (순서 ㅇ)
# 중복순열
itertools.product(arr, repeat=r)
# 중복 가능한 n개 중에 r개 나열
# 조합 ->
itertools.combination(arr, r)
# n개 중에 r개 선택 (순서 X)
for i in range(1 << n):
for j in range(n):
# j가 선택되었을 경우
if i & (1 << j):
print(j, "is in the list")
print("")
visited = [False] * 9
def dfs(v):
visited[v] = True
for i in graph[v]:
if not visited[i]:
dfs(i)
visited = [False] * 9
def bfs(start):
queue = deque([start])
visited[start] = True
while queue:
v = queue.popleft()
for i in graph[v]:
if not visited[i]:
visited[i] = True
queue.append(i)
sys.setrecursionlimit(2500)
런타임 에러 (RecursionError)
방지) 설정하지 않아서 맞은 문제도 틀리는 경우가 많았습니다. xd = [0, 0, 1, -1]
yd = [1, -1, 0, 0]
now_pos = (3, 4)
for i in range(4):
x, y = now_pos
next_pos = (x + xd[i], y + yd[i])