728x90
1. 기본 문법
1.1 변수와 자료형
a = 10 # 정수 (int) — 파이썬은 정수 오버플로우가 없다!
b = 3.14 # 실수 (float)
s = "hello" # 문자열 (str)
flag = True # 불리언 (bool)
파이썬은 타입 선언이 필요 없고, 정수의 크기 제한이 없다. 큰 수 연산 문제에서 매우 유리하다.
1.2 입출력
코딩테스트에서 가장 먼저 부딪히는 부분이다. 이 패턴들은 반드시 외워두자.
# ✅ 정수 하나 입력
n = int(input())
# ✅ 한 줄에 정수 두 개
a, b = map(int, input().split())
# ✅ 한 줄에 여러 정수 → 리스트
nums = list(map(int, input().split()))
# ✅ 여러 줄 입력
n = int(input())
for _ in range(n):
line = input()
# ✅ 빠른 입력 (데이터가 10만 개 이상일 때 필수!)
import sys
input = sys.stdin.readline
# 주의: readline()은 끝에 '\n'이 붙으므로 문자열은 .strip() 필요
s = input().strip()
# 출력
print(a) # 기본 출력
print(a, b) # 공백 구분
print(a, end=" ") # 줄바꿈 대신 공백
print(f"{a} + {b} = {a+b}") # f-string 포매팅
# 빠른 출력 (출력이 많을 때)
import sys
sys.stdout.write(str(a) + "\n")
# 리스트를 공백으로 구분해서 출력
print(*arr) # 언패킹 활용
print(" ".join(map(str, arr)))
1.3 조건문
if x > 0:
print("양수")
elif x == 0:
print("영")
else:
print("음수")
# 삼항 연산자
result = "짝수" if x % 2 == 0 else "홀수"
# 범위 비교 (파이썬만의 편리한 문법)
if 0 <= x < 10:
print("한 자리 수")
# 논리 연산자
if a > 0 and b > 0: # 둘 다 참
if a > 0 or b > 0: # 하나라도 참
if not flag: # 부정
1.4 반복문
# for + range
for i in range(5): # 0, 1, 2, 3, 4
for i in range(1, 6): # 1, 2, 3, 4, 5
for i in range(10, 0, -1): # 10, 9, 8, ..., 1 (역순)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8 (2씩 증가)
# 리스트 순회
for item in arr:
print(item)
# 인덱스와 값 동시에
for i, val in enumerate(arr):
print(i, val)
# while
while n > 0:
n -= 1
# break, continue
for i in range(10):
if i == 5:
break # 반복 종료
if i % 2 == 0:
continue # 다음 반복으로 건너뜀
print(i)
1.5 함수
def add(a, b):
return a + b
# 여러 값 반환
def min_max(arr):
return min(arr), max(arr)
lo, hi = min_max([3, 1, 4, 1, 5])
# 기본값 매개변수
def greet(name="World"):
return f"Hello, {name}!"
# 람다 (정렬에서 자주 사용)
f = lambda x: x[1]
arr.sort(key=lambda x: (x[0], -x[1]))
2. 핵심 자료구조
2.1 리스트 (List)
코딩테스트에서 가장 많이 사용하는 자료구조다.
arr = [1, 2, 3, 4, 5]
# 추가/삭제
arr.append(6) # 뒤에 추가 O(1)
arr.pop() # 마지막 원소 제거 O(1)
arr.pop(0) # 첫 번째 원소 제거 O(n) ⚠️ 느림!
arr.insert(2, 99) # 인덱스 2에 삽입 O(n) ⚠️ 느림!
# 탐색
arr.index(3) # 값 3의 인덱스
3 in arr # 존재 여부 확인 O(n)
arr.count(3) # 3의 개수
# 정렬
arr.sort() # 오름차순 (제자리)
arr.sort(reverse=True) # 내림차순
sorted_arr = sorted(arr) # 원본 유지, 새 리스트 반환
# 뒤집기
arr.reverse() # 제자리
reversed_arr = arr[::-1] # 새 리스트
# 슬라이싱
arr[1:4] # 인덱스 1~3
arr[:3] # 처음~2
arr[2:] # 2~끝
arr[-1] # 마지막 원소
arr[-3:] # 뒤에서 3개
arr[::2] # 짝수 인덱스만
# ⭐ 리스트 컴프리헨션 — 매우 자주 사용!
squares = [x**2 for x in range(10)]
evens = [x for x in arr if x % 2 == 0]
flat = [x for row in matrix for x in row] # 2차원 → 1차원
# ⭐ 2차원 리스트 초기화 (그래프, 행렬 문제 필수)
# ✅ 올바른 방법
grid = [[0] * m for _ in range(n)]
# ❌ 잘못된 방법 (모든 행이 같은 리스트를 참조!)
grid = [[0] * m] * n # 절대 사용하지 말 것!
2.2 문자열 (String)
s = "Hello World"
# 기본 연산
len(s) # 길이
s[0] # 인덱싱
s[1:5] # 슬라이싱
s.lower() # 소문자
s.upper() # 대문자
# 탐색
s.find("World") # 찾은 인덱스 (없으면 -1)
s.count("l") # 개수
"World" in s # 포함 여부
# 변환
s.split() # 공백 기준 분리 → ['Hello', 'World']
s.split(",") # 쉼표 기준 분리
" ".join(["a","b"]) # 합치기 → "a b"
s.strip() # 양쪽 공백 제거
s.replace("o", "0") # 치환
# 문자 판별
c.isdigit() # 숫자?
c.isalpha() # 알파벳?
c.isalnum() # 알파벳 또는 숫자?
# ⭐ 문자열은 불변(immutable)!
# s[0] = 'h' → 에러!
# 수정하려면 리스트로 변환 후 다시 합치기
chars = list(s)
chars[0] = 'h'
s = "".join(chars)
# 아스키코드 변환
ord('a') # 97
chr(97) # 'a'
2.3 딕셔너리 (Dict) — 해시맵
O(1) 탐색이 가능하여 카운팅, 매핑 문제에 필수다.
d = {}
d["apple"] = 3
d["banana"] = 5
# 탐색
if "apple" in d: # 키 존재 확인 O(1)
print(d["apple"])
d.get("cherry", 0) # 없으면 기본값 0 반환
# 순회
for key in d:
print(key, d[key])
for key, val in d.items():
print(key, val)
# 삭제
del d["apple"]
# ⭐ defaultdict — 초기값 자동 설정
from collections import defaultdict
graph = defaultdict(list) # 인접 리스트 만들 때 편리
graph[1].append(2)
graph[1].append(3)
counter = defaultdict(int) # 카운팅
for x in arr:
counter[x] += 1
# ⭐ Counter — 빈도수 카운팅 특화
from collections import Counter
count = Counter([1, 1, 2, 3, 3, 3])
# Counter({3: 3, 1: 2, 2: 1})
count.most_common(2) # 가장 흔한 2개: [(3, 3), (1, 2)]
2.4 셋 (Set)
중복 제거와 O(1) 존재 확인에 사용한다.
s = set([1, 2, 2, 3]) # {1, 2, 3}
s = {1, 2, 3} # 리터럴
s.add(4)
s.remove(2) # 없으면 에러
s.discard(2) # 없어도 에러 없음
if 3 in s: # O(1) 탐색
print("있다")
# 집합 연산
a = {1, 2, 3}
b = {2, 3, 4}
a | b # 합집합 {1, 2, 3, 4}
a & b # 교집합 {2, 3}
a - b # 차집합 {1}
2.5 스택 & 큐
# ✅ 스택 (LIFO) → 리스트 그대로 사용
stack = []
stack.append(1) # push
stack.append(2)
stack.pop() # pop → 2
stack[-1] # peek (제거 없이 확인)
# ✅ 큐 (FIFO) → deque 사용
from collections import deque
q = deque()
q.append(1) # 뒤에 추가
q.append(2)
q.popleft() # 앞에서 제거 O(1)
# ❌ list의 pop(0)은 O(n)이므로 큐에 절대 사용하지 말 것!
# 양방향 큐 (덱)
dq = deque()
dq.appendleft(0) # 앞에 추가
dq.append(1) # 뒤에 추가
dq.popleft() # 앞에서 제거
dq.pop() # 뒤에서 제거
2.6 힙 (우선순위 큐)
import heapq
# 최소 힙 (기본)
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
heapq.heappop(heap) # 1 (가장 작은 값)
heap[0] # peek (제거 없이 최솟값 확인)
# 최대 힙 → 음수 트릭
heapq.heappush(heap, -val)
max_val = -heapq.heappop(heap)
# 리스트를 힙으로 변환
arr = [3, 1, 4, 1, 5]
heapq.heapify(arr) # O(n)
# 튜플 사용 (우선순위 + 데이터)
heapq.heappush(heap, (cost, node)) # cost 기준 정렬
3. 필수 알고리즘
3.1 정렬
# 기본 정렬
arr.sort() # 오름차순
arr.sort(reverse=True) # 내림차순
# 커스텀 정렬
students = [("Kim", 90), ("Lee", 85), ("Park", 90)]
students.sort(key=lambda x: x[1]) # 점수 기준
students.sort(key=lambda x: (-x[1], x[0])) # 점수 내림차 → 이름 오름차
3.2 완전 탐색 (Brute Force)
# 순열 (Permutation)
from itertools import permutations
for p in permutations([1, 2, 3]): # 3! = 6가지
print(p)
for p in permutations([1, 2, 3], 2): # 3P2 = 6가지
print(p)
# 조합 (Combination)
from itertools import combinations
for c in combinations([1, 2, 3, 4], 2): # 4C2 = 6가지
print(c)
# 중복 순열 / 중복 조합
from itertools import product, combinations_with_replacement
for p in product([1, 2, 3], repeat=2): # 9가지
print(p)
3.3 DFS & BFS — 그래프 탐색
코딩테스트에서 가장 자주 출제되는 유형이다.
# 그래프 입력 받기 (인접 리스트)
n, m = map(int, input().split()) # 노드 수, 간선 수
graph = [[] for _ in range(n + 1)]
for _ in range(m):
a, b = map(int, input().split())
graph[a].append(b)
graph[b].append(a) # 양방향
# ✅ BFS (너비 우선 탐색) — 최단 거리 문제에 사용
from collections import deque
def bfs(graph, start):
visited = [False] * len(graph)
q = deque([start])
visited[start] = True
while q:
node = q.popleft()
print(node, end=" ")
for neighbor in graph[node]:
if not visited[neighbor]:
visited[neighbor] = True
q.append(neighbor)
# ✅ DFS (깊이 우선 탐색) — 재귀 버전
def dfs(graph, node, visited):
visited[node] = True
print(node, end=" ")
for neighbor in graph[node]:
if not visited[neighbor]:
dfs(graph, neighbor, visited)
# ✅ DFS — 스택 버전 (재귀 깊이 제한 회피)
def dfs_stack(graph, start):
visited = [False] * len(graph)
stack = [start]
while stack:
node = stack.pop()
if visited[node]:
continue
visited[node] = True
print(node, end=" ")
for neighbor in graph[node]:
if not visited[neighbor]:
stack.append(neighbor)
# ⭐ 2차원 격자 BFS (미로 탐색, 최단 거리)
from collections import deque
def bfs_grid(grid, start_r, start_c):
n, m = len(grid), len(grid[0])
dist = [[-1] * m for _ in range(n)]
dist[start_r][start_c] = 0
q = deque([(start_r, start_c)])
dr = [-1, 1, 0, 0] # 상하좌우
dc = [0, 0, -1, 1]
while q:
r, c = q.popleft()
for d in range(4):
nr, nc = r + dr[d], c + dc[d]
if 0 <= nr < n and 0 <= nc < m:
if grid[nr][nc] == 1 and dist[nr][nc] == -1:
dist[nr][nc] = dist[r][c] + 1
q.append((nr, nc))
return dist
3.4 이진 탐색 (Binary Search)
# 직접 구현
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1
# bisect 모듈 활용
from bisect import bisect_left, bisect_right
sorted_arr = [1, 2, 3, 3, 3, 4, 5]
bisect_left(sorted_arr, 3) # 2 (3이 처음 나타나는 위치)
bisect_right(sorted_arr, 3) # 5 (3보다 큰 첫 위치)
# 특정 값의 개수
count = bisect_right(sorted_arr, 3) - bisect_left(sorted_arr, 3) # 3
# ⭐ 매개변수 탐색 (Parametric Search) 패턴
# "조건을 만족하는 최댓값/최솟값을 구하라"
def parametric_search():
lo, hi = 최솟값, 최댓값
while lo <= hi:
mid = (lo + hi) // 2
if check(mid): # 조건 만족?
answer = mid
lo = mid + 1 # 더 큰 값 시도
else:
hi = mid - 1
return answer
3.5 다이나믹 프로그래밍 (DP)
# 피보나치 — 탑다운 (메모이제이션)
dp = {}
def fib(n):
if n <= 1:
return n
if n in dp:
return dp[n]
dp[n] = fib(n-1) + fib(n-2)
return dp[n]
# 피보나치 — 바텀업 (반복문) ✅ 코테에서 더 안정적
def fib(n):
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
# ⭐ 대표 DP 패턴: 배낭 문제 (Knapsack)
def knapsack(n, capacity, weights, values):
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(capacity + 1):
if weights[i-1] <= w:
dp[i][w] = max(dp[i-1][w],
dp[i-1][w - weights[i-1]] + values[i-1])
else:
dp[i][w] = dp[i-1][w]
return dp[n][capacity]
3.6 그리디 (Greedy)
매 순간 최적의 선택을 하는 전략이다. 정렬 + 순회 패턴이 많다.
# 예시: 회의실 배정 (끝나는 시간 기준 정렬)
meetings = [(1,4), (2,3), (3,5), (4,6)]
meetings.sort(key=lambda x: x[1]) # 끝나는 시간 오름차순
count = 0
end_time = 0
for start, end in meetings:
if start >= end_time:
count += 1
end_time = end
3.7 최단 경로
# 다익스트라 (Dijkstra) — 양의 가중치 그래프
import heapq
def dijkstra(graph, start, n):
INF = float('inf')
dist = [INF] * (n + 1)
dist[start] = 0
pq = [(0, start)] # (비용, 노드)
while pq:
cost, node = heapq.heappop(pq)
if cost > dist[node]:
continue
for next_node, weight in graph[node]:
new_cost = cost + weight
if new_cost < dist[next_node]:
dist[next_node] = new_cost
heapq.heappush(pq, (new_cost, next_node))
return dist
# 플로이드-워셜 (Floyd-Warshall) — 모든 쌍 최단 경로
def floyd(n, edges):
INF = float('inf')
dist = [[INF] * (n + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
dist[i][i] = 0
for a, b, cost in edges:
dist[a][b] = cost
for k in range(1, n + 1):
for i in range(1, n + 1):
for j in range(1, n + 1):
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
return dist
4. 자주 쓰는 내장 함수와 라이브러리
4.1 내장 함수
# 수학
abs(-5) # 5
max(1, 2, 3) # 3
min(arr) # 리스트 최솟값
sum(arr) # 합계
pow(2, 10) # 1024
divmod(7, 3) # (2, 1) → 몫과 나머지 동시에
# 형변환
int("123") # 정수 변환
str(123) # 문자열 변환
list("abc") # ['a', 'b', 'c']
tuple([1, 2, 3]) # (1, 2, 3)
# 기타
len(arr) # 길이
sorted(arr) # 정렬된 새 리스트
reversed(arr) # 역순 이터레이터
enumerate(arr) # (인덱스, 값) 쌍
zip(a, b) # 병렬 순회
map(int, ["1","2"]) # 모든 원소에 함수 적용
any([F, F, T]) # 하나라도 True면 True
all([T, T, T]) # 모두 True면 True
4.2 math 모듈
import math
math.gcd(12, 8) # 최대공약수 4
math.lcm(4, 6) # 최소공배수 12 (Python 3.9+)
math.sqrt(16) # 4.0
math.ceil(3.2) # 4 (올림)
math.floor(3.8) # 3 (내림)
math.log2(8) # 3.0
math.factorial(5) # 120
math.inf # 무한대
math.comb(5, 2) # 5C2 = 10 (Python 3.8+)
4.3 itertools 모듈
from itertools import permutations, combinations
from itertools import product, combinations_with_replacement
from itertools import accumulate, chain
# 누적합
list(accumulate([1, 2, 3, 4])) # [1, 3, 6, 10]
# 여러 리스트 합치기
list(chain([1,2], [3,4], [5,6])) # [1, 2, 3, 4, 5, 6]
4.4 기타 유용한 모듈
# 정규표현식
import re
numbers = re.findall(r'\d+', "abc123def456") # ['123', '456']
# 깊은 복사
import copy
new_grid = copy.deepcopy(grid) # 2차원 리스트 복사할 때
# 무한대
INF = float('inf')
# 재귀 깊이 제한 늘리기 (DFS 전에 설정)
import sys
sys.setrecursionlimit(10**6)728x90
'Programming Language > Python' 카테고리의 다른 글
| [Python] 파이썬은 무엇인가 그리고 특징은? (0) | 2023.09.10 |
|---|