파이썬 코딩테스트 꿀팁 노트 (feat. 코테 벼락치기)

Woonil·2025년 3월 10일
0

알고리즘

목록 보기
33/38

코딩테스트를 시행할 때 도움이 될만한 나만의 팁이 담긴 코드 노트이다. 이 노트에는 코드 작성 중 간과할 만한 부분이나, 꿀팁들이 담겨있다. 파이썬으로 코딩테스트를 보는데, 시험이 바로 다음날인 사람들에게 도움이 되었으면 한다. 지속적으로 업데이트 할 예정이다.

활용도 ⭐

2차원 배열

최댓값(최솟값) 구하기

# map을 활용
mount = [list(map(int, input().split()) for _ in range(n)]
dep = min(map(min, mount)) 
arr = max(map(max, mount))

두 가지 정보를 저장

# 한 좌표에 두 가지 정보를 가짐
ch = [[[0] * 2 for _ in range(m)] for _ in range(n)]

90도 회전

def rotate_a_matrix_by_90_degree(a):
    n = len(a) # 행 길이
    m = len(a[0]) # 열 길이
    result = [[0] * n for _ in range(m)]
    for i in range(n):
        for j in range(m):
            result[j][n - i - 1] = a[i][j]

    return result

부분 반복문

몫과 인덱스 범위를 활용하여 접근

# 스도쿠 풀이 중 3X3 부분 확인 코드 중
def checkRect(x, y, a):
    nx = x // 3 * 3
    ny = y // 3 * 3
    for i in range(3):
        for j in range(3):
            if a == graph[nx + i][ny + j]:
                return False
    return True

3차원 배열

초기화

3개 이상의 정보를 3차원 배열로 초기화해야 하는 경우가 생긴다.

# 3개의 레이어를 가지는 2차원 배열
dp = [[[0 for _ in range(N)] for _ in range(N)] for _ in range(3)]

여러 줄 입력 받기

arr = []
m, n, h = map(int, input().split())
for _ in range(h):
    tmp = []
    for _ in range(n):
        tmp .append(list(map(int, input().split())))
    arr.append(box)

접근

for i in range(len(tmt)):
    for j in range(n):
        for k in range(m):
            if **tmt[i][j][k]** == 1: # 인덱스 순서에 유의

삼중 반복문

전역에서 삼중 이상의 반복문을 사용할 경우 for 반복문 내 변수 선언 중복에 유의한다. (i, j, k, …)

...
for i in range(n): # i
    for j in range(n): # j
        if islands[i][j] == 1:
            cnt += 1
            islands[i][j] = 0
            q.append((i, j))
            while q:
                x, y = q.popleft()
                for k in range(8):
                    nx = x + dx[k] # k
                    ny = y + dy[k]
...

리스트에 숫자가 섞여있을 때 문자열 반환

리스트 컴프리헨션 → 형 변환: str() → 배열을 문자열로 합치기: join()

' '.join(str(arr) for arr in arrs)

문자 순서부여

아스키코드 활용

ord() 함수를 사용하여 알파벳의 아스키코드를 활용한다.

# input_data에 a부터의 알파벳이 순서대로 있는 경우
index= int(ord(input_data[0])) - int(ord('a')) + 1

진법 변환

2, 8, 16진수로의 전환

bin() , oct() , hex() 각각 진수 형태의 문자열로 변환되며, ‘0b’, ‘0o’, ‘0x’가 접두어로 붙는다.

10진수로의 전환

int('...', base) base에는 2, 8, 16이 올 수 있다. (base의 디폴트는 10)

숫자 만들기

입력된 값을 순서대로 추가하여 숫자 만드는 쉬운 방법 (0으로 시작하는 숫자는 무시됨)

n = input()
num = 0
for x in n:
    if x.isdecimal():
				# 기존값에 10을 곱한 후 입력값을 더함
        num = num * 10 + int(x)

결괏값 갱신

첫번째 값을 결괏값으로 설정

첫번째 값을 포함한 결괏값이 이후의 연속된 연산으로 갱신될 때 유용하다.

# 곱하기 혹은 더하기 풀이 중
s = input()
first = int(s[0])
result = first # 첫번째 값을 결괏값으로 설정
for num in s[1:]: # 이후 연산이 이어짐
  num = int(num)
  if result <= 1 or num <= 1:
    result += num
  else:
    result *= num

0 미만으로 내려갈 수 없는 값 초기화하기

# 빙산의 높이는 음수가 될 수 없다는 조건
ice[i][j] = max(0, ice[i][j]-cnt[i][j])

check 배열

set() 활용

  • 체크 배열 초기화 매번 깊이 탐색 시 중복된 값을 제외해야 하는 경우, 기존의 check배열을 set()로 설정할 수 있다.
    from collections import deque
    
    def solution(x, y, n):
        queue = deque()
        queue.append((x,0))
        visited = set() # 포인트
        while queue:
            i, j = queue.popleft()
            if i>y or i in visited:
                continue
            visited.add(i)
            if i==y: 
                return j
            for k in (i*3,i*2,i+n):
                if k<=y and k not in visited:
                    queue.append((k,j+1))    
        return -1
  • 체크 배열 조작 check를 1로 설정, 0으로 설정 하는 과정을 세트에 넣었다 뺐다 하는 과정으로 변경할 수 있다.
    check = set(alph_board[0][0])
    
    def dfs(x, y, cnt):
        ...
            if 0 <= nx < R and 0 <= ny < C:
                if alph_board[nx][ny] not in check:
                    check.add(alph_board[nx][ny])
                    dfs(nx, ny, cnt + 1)
                    check.remove(alph_board[nx][ny])
    
    dfs(0, 0, ans)

활용도 ⭐⭐

순환 문자열 또는 리스트

원래 문자열을 탐색해야 할 인덱스까지 자른 후, 한번 더 원래 문자열에 이어 붙이면 순환 문자열을 구현할 수 있다.

# [프로그래머스] 연속 부분 수열 합의 개수 풀이 중
def solution(elements):
    elements=elements*2

2차원 배열 입력받기 (백준, 소프티어와 같이 입력값을 직접 받는 경우에만 해당)

N줄의 연속된 입력값으로 2차원 배열 생성

  • append()
    N = int(input())
    graph = []  
    for _ in range(1, N + 1):
      graph.append(list(map(int, input().split())))
  • 리스트 컴프리헨션
    • 일반 input()
      alph_board = [list(input()) for _ in range(R)]
      # 정수형으로 변환
      alph_board = [list(map(int, input().split())) for _ in range(R)]
    • input = sys.stdin.readline를 적용한 input() rstrip()함수로 \n 을 지워줘야 한다. (예외 상황 방지)
      import sys
      input = sys.stdin.readline
      
      alph_board = [list(input().rstrip()) for _ in range(R)]

N줄의 입력값으로 2차원 배열 생성

각 행의 리스트에서 특정 인덱스를 추출할 때 유용

a, b = -1, -1
mount = []
for i in range(n):
    line = list(map(int, input().split())) # append로 각 행을 추가
    for j in range(n):
        if line[j] < dep:
					dep = line[j]
          a, b = i, j
    mount.append(line)

한줄의 연속된 입력값으로 2차원 배열 생성

  • 배열 슬라이싱
    ## 2차원 DP 생성 예시 ##
    # 배열 선언 후, 연속된 입력값을 담음
    array = list(map(int, input().split()))
    # 인덱스 슬라이싱을 활용하여 배열 특정구간을 잘라내어
    # 다른 배열에 추가함 (슬라이싱 시작점을 계속 가로크기만큼 
    # 더하여 초기화해야함)
    dp = []
    index = 0
    for i in range(n):
      dp.append(array[index:index + m])
    index += m # 슬라이싱 시작점 초기화

인덱스 고려가 필요없는 배열 생성

n, m = map(int, input().split())
tmp_board = [[0] * (n + 1)]

for _ in range(n):
    tmp_line = list(map(int, input().split()))
    tmp_board.append([0] + tmp_line)

반복문의 결과를 리스트로 반환

# 리스트 컴프리헨션 + list() 또는 []
cards = list(i for i in range(0, 21))
cards = [i for i in range(0, 21)] 

반복문 + else

for, while 반복문에서 break를 만나지 않고 정상적으로 종료될 경우, 단독 else를 실행할 수 있다.

for char in str_1:
    d[char] += 1
for char in str_2:
    if char in d:
        d[char] -= 1
    else:
        print('NO')
        break
for key, val in d.items():
    if val != 0:
        print('NO')
        break
else:
    print('YES')

재귀 깊이 설정

import sys
# 깊이 제한이 걸려있는 경우 문제를 통과하려면 제한을 늘려야 함
sys.setrecursionlimit(10 ** 6)

좌표 설정

방향을 담은 리스트 직접 생성

steps= [(0, -1), (0, 1), (-1, 0), (1, 0)]

dx dy 설정

dx= [0, 0, -1, 1]
dy= [-1, 1, 0, 0]

간선 정보 입력

연결 리스트 구현

빈 리스트를 인덱스별로 추가하고, 정점 a와 인접한 정점 b들을 저장한다.

graph = [[] for _ in range(n + 1)]

for _ in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a) # 양방향 그래프인 경우

문자열, 리스트 더하기

문자열

  • += 문자열이나 배열에 추가하는 경우
    • 출력 형식이 문자열일 때, 초기 문자열을 ‘’로 초기화하고 += 로 이어붙이는 형식으로 전개할 수 있다.
    • 문자열끼리 ‘+’를 사용하여 연결할 수 있으며, 정수형과 같이 다른 자료형은 str() 으로 형변환 후 연결해야 한다.

리스트

  • append() 배열에 원소(배열 포함)를 추가하는 경우
  • +, extend() 리스트끼리 더할 때는 +, extend() 함수를 사용할 수 있다.
    # +
    if ap == len(a):
        ans + b[bp:]
    # extend
    if ap == len(a):
        ans.extend(b[bp:])

print

구분자 지정하기

  • sep print에 이 속성을 사용할 수 있다.

인덱스 범위에 따른 반복문 실행

배열의 길이 활용

for i in range(len(list) // 2):
  sum += int(n[i])

몫 구하기

연산자 사용

# 몫 연산자(//) 사용 (이진탐색 소스코드 구현 중)
mid= (start + end) // 2 

int() 활용

int() : 몫 이하는 버린다.

# 큰 수의 법칙 소스코드 중
count= int(m / (k+1)) * k

세트

정렬

sarr.sort()
ssarr=set(sarr) # 정렬 무시됨
# set는 정렬 순서를 무시하고 재배치하므로 set() 진행 후, 정렬해야 함에 유의
sarr=list(set(arr))
sarr.sort() 

직사각형 형태의 배열

m, n이 각각 행,열 중 무엇과 대응하는지 정확히 확인

범위 조사

...
if 0 <= nx < n and 0 <= ny < m: # m: 가로, n: 세로
...

append로 배열 생성 시 유의

m, n = map(int, input().split()) # m: 가로, n: 세로
tmts = []
cnt = 0
q = deque()
for i in range(n): # for문: n -> m
    line = list(map(int, input().split()))
    for j in range(m):
        if line[j] == 1:
            q.append((i, j, 0))
        if line[j] == 0:
            cnt += 1
    tmts.append(line)

불리언으로 값 갱신하기

dfs(l+1,cnt+int(arr[l][0]<=0)+int(arr[i][0]<=0))

활용도 ⭐⭐⭐

from collections import deque

seq = list(map(int, input().split()))
seq = deque(seq)

많은 입력 받기

sys 라이브러리

import sys
input = sys.stdin.readline # input으로 치환하여 코드길이를 줄임

여러 변수에 할당

split()을 사용하여 입력 값들을 띄어쓰기를 기준으로 여러 변수에 할당

add, sub, mul, div = map(int, input().split())

최댓값&최솟값 초기화

무한대 값 설정

파이썬에서는 임의의 큰 값을 ‘무한’으로 여길 때 int(1e9)와 같이 e를 사용할 수 있다.

1e9 = 1*10^9 = 1,000,000,000

min(max) 함수 활용

값 초기화 후 갱신

최댓값 또는 최솟값을 구하는 과정이 있는 문제에서 초기값을 무한대나, 매우 작은 음수 등 초기값을 설정한 후 그 값과 비교하여 갱신하거나 그대로 유지한다.

result = len(s) 
# result를 s의 길이으로 초기화 (이후 min 함수를 통해 최솟값으로 갱신 위해)
result = min(result, len(compressed)) 
# 기존의 result값과 현재 압축된 문자열의 길이를 비교하여 result값 갱신

동적으로 배열 슬라이싱 끝 범위 지정하기

for g in gd.keys():
        tmp=[k for k,[genre,_] in d.items() if genre==g]
        # min(max) 함수를 활용하여 간단하게 끝 범위를 동적으로 지정
        ans+=tmp[:min(len(tmp),2)]

숫자 최대 연속횟수 구하기

def max_seq_cap(line):
  max_count = 1 # 최댓값 초기화
  count = 1 
  for i in range(0, len(line)-1):
    if line[i] == line[i+1]:
      count += 1
    else:
      max_count = max(count, max_count) 
      count = 1 # count 초기화
  return max(count, max_count) 

return max(count, max_count)

예외처리 위해 반환값에서도 적용 ex) line = [1, 1, 1] 처럼 모든 원소가 같은 경우 if문만 돌기 때문에 max_count 값이 초기화되지 않는다.

연속된 입력값 중 최대최소 찾기

연속된 입력을 받은 후 리스트로 변환하여 min() 또는 max()를 이용하여 최솟값 또는 최댓값을 구한다.

# 최솟값 중 최댓값 구하기
result = 0 # 값 초기화 후 갱신 방법을 사용
for i in range(n):
	data = list(map(int, input().split()))
	min_value = min(data)
	result = max(result, min_value)

인덱스로 바로 리스트에 접근

허깨비 세우기

OutOfIndex Error를 피해갈 수 있다.

  • 처음에 세우기: 0을 채워넣음으로 인덱스를 숫자 그 자체로 접근 가능
    # 예시) 다익스트라 구현 소스 코드 중 
    # 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트
    graph = [[] for i in range(n+1)]
  • 마지막에 세우기: 인덱스 0, 마지막 인덱스 + 1
    # 프로그래머스 체육복 구현 소스 코드 중
    u = [1] * (n + 2)
    for i in range(1, n + 1):
            if u[i - 1] == 0 and u[i] == 2:
                u[i - 1:i + 1] = [1, 1]
            elif u[i + 1] == 0 and u[i] == 2:
                u[i:i + 2] = [1, 1]

리스트 초기화

[0] *

False 대신 0을 사용하면 sum() 을 활용하여 합계 조건에 활용 가능하다.

robots = [0] * n
if sum(robots):
 ...

2차원 배열 초기화

리스트 표현식

# for 반복문을 한 번 사용하여 식 부분에서 리스트 자체를 곱해주는 방식
dp = [[0] * (x + 1) for x in range(n)] # 계단모양의 2차원 배열을 초기화

딕셔너리

defaultdict()

딕셔너리의 디폴트 값을 지정할 필요가 없다. (데이터 타입, 리스트, 세트 등이 인자로 넘겨짐)

from collections import defaultdict

def solution(input_string):
    d = defaultdict(int)
    prev = None
    for cur in input_string:
        if cur != prev:
            d[cur] += 1
        prev = cur

정렬

기본적으로 딕셔너리를 정렬하면 keys를 기준으로 정렬되므로, 값에 대한 정렬 시 items를 통해 리스트를 먼저 추출한 후 정렬한 후, 다시 딕셔너리로 바꿔줘야 한다. (items() 로 키, 값을 불러온 후, 람다함수를 통해 정렬)

  • 값 정렬
    play_sums = defaultdict(int)
    sorted(play_sums.items(), key = lambda x: -x[1]) # 값에 대한 내림차순 정렬
    play_sums = dict(sorted(play_sums.items(), key = lambda x: -x[1])) # 정렬 후 다시 딕셔너리로 변환
  • 키-값 모두 정렬
    data = dict(sorted(data.items(), key = lambda x: (-x[1][0], x[0])))
profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글

관련 채용 정보