Changyu Lee

코테 대비 Python 주요 자료구조와 내장 함수들 정리 (수정판)

Published at
2025/11/07
Last edited time
2025/11/12 01:55
Created
2025/11/07 23:18
Section
Algorithm
Status
In progress
Series
Tags
Basic
AI summary
Keywords
Coding Test
Language
KOR
Week

Python

1. Array

# 리스트 생성 및 기본 연산 arr = [1, 2, 3, 4, 5] arr.append(6) # 끝에 추가 arr.insert(0, 0) # 인덱스 0에 삽입 arr.pop() # 마지막 요소 제거 arr.pop(0) # 인덱스 0 제거 arr.remove(3) # 값 3 제거 # 정렬 arr.sort() # 오름차순 정렬 (in-place) arr.sort(reverse=True) # 내림차순 정렬 sorted(arr) # 새 리스트 반환 # 슬라이싱 arr[1:4] # 인덱스 1~3 arr[::-1] # 뒤집기 # 리스트 컴프리헨션 squares = [x**2 for x in range(10)] evens = [x for x in arr if x % 2 == 0] # 기타 len(arr), min(arr), max(arr), sum(arr) arr.count(2) # 값 2의 개수 arr.index(3) # 값 3의 인덱스
Python
복사

1-1. 슬라이싱 [::k]와 [:k] 차이

# [:k] - 처음부터 k-1번째 인덱스까지 arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] arr[:5] # [0, 1, 2, 3, 4] (0~4번 인덱스) arr[:3] # [0, 1, 2] (0~2번 인덱스) # [::k] - 처음부터 끝까지 k 간격으로 arr[::2] # [0, 2, 4, 6, 8] (0부터 2칸씩) arr[::3] # [0, 3, 6, 9] (0부터 3칸씩) arr[::1] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (원본과 동일) # [::k]는 step 파라미터, [:k]는 end 파라미터 # 형식: [start:end:step] arr[1:7:2] # [1, 3, 5] (1번부터 6번까지 2칸씩) arr[2::3] # [2, 5, 8] (2번부터 끝까지 3칸씩) # 음수 step으로 역순 arr[::-1] # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (전체 뒤집기) arr[::-2] # [9, 7, 5, 3, 1] (끝에서부터 2칸씩) arr[8:2:-1] # [8, 7, 6, 5, 4, 3] (8번부터 3번까지 역순) # 문자열에서도 동일하게 작용 s = "abcdefghij" s[:5] # "abcde" s[::2] # "acegi" s[::-1] # "jihgfedcba"
Python
복사

1-2. 리스트에서 중복 제거

# set을 이용한 중복 제거 (순서 보장 안됨) arr = [1, 2, 2, 3, 4, 4, 5] unique_arr = list(set(arr)) # [1, 2, 3, 4, 5] (순서 무작위) # 순서를 유지하면서 중복 제거 (dict.fromkeys 사용) arr = [1, 2, 2, 3, 4, 4, 5] unique_arr = list(dict.fromkeys(arr)) # [1, 2, 3, 4, 5] (순서 유지) # 순서를 유지하면서 중복 제거 (리스트 컴프리헨션) arr = [1, 2, 2, 3, 4, 4, 5] seen = set() unique_arr = [x for x in arr if not (x in seen or seen.add(x))] # [1, 2, 3, 4, 5] # 리스트 안의 리스트 중복 제거 arr = [[1, 2], [3, 4], [1, 2], [5, 6]] unique_arr = [list(x) for x in set(tuple(x) for x in arr)] # [[1, 2], [3, 4], [5, 6]] # Counter를 이용한 중복 제거 및 빈도수 확인 from collections import Counter arr = [1, 2, 2, 3, 4, 4, 5] counter = Counter(arr) # Counter({2: 2, 4: 2, 1: 1, 3: 1, 5: 1}) unique_arr = list(counter.keys()) # [1, 2, 3, 4, 5]
Python
복사

1-3. 2차원 배열에서 중복 제거

# 2차원 배열 (리스트의 리스트) 중복 제거 arr_2d = [[1, 2], [3, 4], [1, 2], [5, 6], [3, 4]] # tuple로 변환 후 set 사용 (순서 보장 안됨) unique_2d = [list(x) for x in set(tuple(row) for row in arr_2d)] # [[1, 2], [3, 4], [5, 6]] (순서 무작위) # 순서를 유지하면서 중복 제거 seen = set() unique_2d = [] for row in arr_2d: row_tuple = tuple(row) if row_tuple not in seen: seen.add(row_tuple) unique_2d.append(row) # [[1, 2], [3, 4], [5, 6]] (순서 유지) # 리스트 컴프리헨션으로 순서 유지 seen = set() unique_2d = [row for row in arr_2d if tuple(row) not in seen and not seen.add(tuple(row))] # [[1, 2], [3, 4], [5, 6]] # 각 행을 정렬한 후 중복 제거 (순서 무관 중복) arr_2d = [[1, 2], [2, 1], [3, 4], [4, 3]] unique_2d = [list(x) for x in set(tuple(sorted(row)) for row in arr_2d)] # [[1, 2], [3, 4]] # numpy 사용 (큰 배열에 효율적) import numpy as np arr_2d = [[1, 2], [3, 4], [1, 2], [5, 6]] unique_2d = np.unique(np.array(arr_2d), axis=0).tolist() # [[1, 2], [3, 4], [5, 6]]
Python
복사

1-4. 리스트에서 최댓값/최솟값 찾기

# 최댓값과 최솟값 arr = [3, 7, 1, 9, 4] max_val = max(arr) # 9 min_val = min(arr) # 1 # 최댓값의 인덱스 max_idx = arr.index(max(arr)) # 3 # 여러 최댓값이 있을 때 모든 인덱스 찾기 arr = [9, 3, 9, 1, 9] max_val = max(arr) max_indices = [i for i, x in enumerate(arr) if x == max_val] # [0, 2, 4] # 조건부 최댓값 arr = [3, 7, 1, 9, 4] max_even = max([x for x in arr if x % 2 == 0]) # 4 max_odd = max([x for x in arr if x % 2 != 0]) # 9 # 2차원 배열에서 최댓값 arr_2d = [[1, 5, 3], [9, 2, 7], [4, 6, 8]] max_val = max(max(row) for row in arr_2d) # 9 # key 함수를 사용한 최댓값 words = ["apple", "banana", "kiwi"] longest = max(words, key=len) # "banana" (가장 긴 문자열) # 딕셔너리에서 최댓값 d = {'a': 10, 'b': 25, 'c': 5} max_key = max(d, key=d.get) # 'b' (값이 가장 큰 키) max_val = max(d.values()) # 25 # 튜플 리스트에서 특정 요소 기준 최댓값 students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)] top_student = max(students, key=lambda x: x[1]) # ("Bob", 92)
Python
복사

2. heapq 사용법 (최소 힙 기반)

import heapq # 기본 힙(최소 힙) h = [] heapq.heappush(h, 3) heapq.heappush(h, 1) heapq.heappush(h, 5) print(h[0]) # 최소값 조회 print(heapq.heappop(h)) # 최소값 꺼내기 # 리스트를 힙으로 변환 arr = [7, 2, 9, 1] heapq.heapify(arr) # 최대 힙(음수 변환) maxh = [] for x in [3,1,5]: heapq.heappush(maxh, -x) print(-heapq.heappop(maxh)) # 최대값 # 상위/하위 k개 nums = [9,1,5,3,7] print(heapq.nsmallest(3, nums)) # [1,3,5] print(heapq.nlargest(2, nums)) # [9,7]
Python
복사

3. deque 사용법 (양쪽 O(1) 삽입/삭제)

from collections import deque dq = deque([1,2,3]) # 양쪽 삽입/삭제 dq.append(4) # 오른쪽에 추가 dq.appendleft(0) # 왼쪽에 추가 dq.pop() # 오른쪽 제거 dq.popleft() # 왼쪽 제거 # 기타 dq.rotate(1) # 오른쪽으로 회전 dq.rotate(-2) # 왼쪽으로 회전 print(len(dq), dq[0], dq[-1]) for i in range(m): for k in range(n): if visited[i][k] or grid[i][k] == "0": continue queue = deque([(i, k)]) visited[i][k] = True num += 1 while queue: x, y = queue.popleft() for dx, dy in dirs: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n: if not visited[nx][ny] and grid[nx][ny] == "1": visited[nx][ny] = True queue.append((nx, ny))
Python
복사

4. 문자열(str) 관련 패턴

s = " Hello, Python 3.10! " # 길이/접근 len(s), s[0], s[-1], s[2:7], s[::-1] # 문자열 뒤집기 # 공백 제거 s.strip(), s.lstrip(), s.rstrip() # 분할/결합 "John,Doe".split(",") " ".join(["a","b","c"]) # 찾기/검사 s.find("Python"), s.count("o") s.startswith("He"), s.endswith("!") # 치환 "2025-09-23".replace("-", "/") # 대소문자 "heLLo".lower(), "heLLo".upper(), "abc".title() # 포맷팅 f"Alice got {97.5:.1f}" "{:,.0f}".format(1234567) # 판별 "123".isdigit(), "abc".isalpha(), "a1".isalnum()
Python
복사

4-1. 문자열 정렬

# 문자열 정렬 s = "dcba" sorted_s = ''.join(sorted(s)) # "abcd" (오름차순) sorted_desc = ''.join(sorted(s, reverse=True)) # "dcba" (내림차순) # 대소문자 구분 없이 정렬 mixed = "aBcD" ''.join(sorted(mixed, key=str.lower)) # "aBcD" # 문자열 리스트 정렬 words = ["banana", "apple", "cherry"] words.sort() # in-place 정렬 sorted_words = sorted(words) # 새 리스트 반환 # 길이 기준 정렬 sorted(words, key=len) # 길이 짧은 순 # 특정 인덱스 기준 정렬 sorted(words, key=lambda x: x[1]) # 두 번째 문자 기준
Python
복사

4-2. 문자열 특정 문자 삭제 및 변환

# 특정 문자 삭제 s = "Hello, World!" s.replace(",", "") # "Hello World!" (쉼표 삭제) s.replace(" ", "") # "Hello,World!" (공백 삭제) # 여러 문자 삭제 (translate 사용) import string s = "Hello123World456" s.translate(str.maketrans('', '', string.digits)) # "HelloWorld" (숫자 제거) # 특정 문자들만 남기기 (filter 사용) s = "a1b2c3" ''.join(filter(str.isalpha, s)) # "abc" (알파벳만) ''.join(filter(str.isdigit, s)) # "123" (숫자만) # 정규표현식 사용 import re s = "Hello123World456" re.sub(r'\d', '', s) # "HelloWorld" (숫자 삭제) re.sub(r'[^a-zA-Z]', '', s) # "HelloWorld" (알파벳만) re.sub(r'\s+', '', s) # 모든 공백 삭제 # 특정 문자 제거 (리스트 컴프리헨션) s = "Hello, World!" remove_chars = {',', '!', ' '} ''.join([c for c in s if c not in remove_chars]) # "HelloWorld" # 문자 치환 (여러 개) s = "apple banana cherry" trans = str.maketrans({'a': '1', 'e': '2', 'i': '3'}) s.translate(trans) # "1ppl2 b1n1n1 ch2rry"
Python
복사

4-3. 알파벳만 남기기

# filter 사용 s = "Hello123World456!@#" ''.join(filter(str.isalpha, s)) # "HelloWorld" (알파벳만) # 리스트 컴프리헨션 ''.join([c for c in s if c.isalpha()]) # "HelloWorld" # 정규표현식 사용 import re re.sub(r'[^a-zA-Z]', '', s) # "HelloWorld" (알파벳이 아닌 것 제거) # 대소문자 구분 re.sub(r'[^a-z]', '', s.lower()) # 소문자만 re.sub(r'[^A-Z]', '', s.upper()) # 대문자만
Python
복사

4-4. 알파벳과 숫자만 남기기

# filter 사용 s = "Hello123World456!@#" ''.join(filter(str.isalnum, s)) # "Hello123World456" (알파벳+숫자만) # 리스트 컴프리헨션 ''.join([c for c in s if c.isalnum()]) # "Hello123World456" # 정규표현식 사용 import re re.sub(r'[^a-zA-Z0-9]', '', s) # "Hello123World456" (알파벳+숫자가 아닌 것 제거) # 특정 케이스 s = "User@123!Name#456" ''.join(filter(lambda c: c.isalpha() or c.isdigit(), s)) # "User123Name456" # 공백 포함하여 남기기 s = "Hello 123 World!@#" re.sub(r'[^a-zA-Z0-9\s]', '', s) # "Hello 123 World" (알파벳+숫자+공백만)
Python
복사

5. set 사용법 (중복 제거, 집합 연산) → HashMap

# 집합 생성 s = {1, 2, 3} s = set([1, 2, 2, 3]) # [1, 2, 3] # 추가/제거 s.add(4) # 요소 추가 s.remove(2) # 요소 제거 (없으면 에러) s.discard(2) # 요소 제거 (없어도 에러 없음) s.pop() # 임의의 요소 제거 및 반환 s.clear() # 전체 제거 # 집합 연산 a = {1, 2, 3} b = {2, 3, 4} a | b # 합집합: {1, 2, 3, 4} a & b # 교집합: {2, 3} a - b # 차집합: {1} a ^ b # 대칭차집합: {1, 4} a.union(b) a.intersection(b) a.difference(b) a.symmetric_difference(b) # 검사 2 in s # 포함 여부 a.issubset(b) # 부분집합 여부 a.issuperset(b) # 상위집합 여부 # 변환 list(s) # 리스트로 변환 sorted(s) # 정렬된 리스트로 len(s) # 크기 #조회 s.get(chat, 0) # chat 에 해당하는 값 or 0
Python
복사

6. enumerate 사용법 (인덱스와 값 동시 순회)

# 기본 사용법 arr = ['a', 'b', 'c'] for i, val in enumerate(arr): print(i, val) # 0 a, 1 b, 2 c # 시작 인덱스 지정 for i, val in enumerate(arr, start=1): print(i, val) # 1 a, 2 b, 3 c # 리스트로 변환 list(enumerate(arr)) # [(0, 'a'), (1, 'b'), (2, 'c')] # 조건부 인덱스 찾기 arr = [10, 20, 30, 40] indices = [i for i, x in enumerate(arr) if x > 15] # [1, 2, 3] # 딕셔너리 생성 dict(enumerate(arr)) # {0: 10, 1: 20, 2: 30, 3: 40} # 문자열에 사용 s = "hello" for i, char in enumerate(s): print(f"{i}: {char}") # 0: h, 1: e, ...
Python
복사

7. Sorting 정리

# set 정렬 s = {3, 1, 4, 1, 5} sorted_list = sorted(s) # [1, 3, 4, 5] (리스트로 반환) sorted_desc = sorted(s, reverse=True) # [5, 4, 3, 1] (내림차순) # 딕셔너리 정렬 (key 기준) d = {'c': 3, 'a': 1, 'b': 2} sorted_by_key = sorted(d.items()) # [('a', 1), ('b', 2), ('c', 3)] sorted_by_key_desc = sorted(d.items(), reverse=True) # [('c', 3), ('b', 2), ('a', 1)] # 딕셔너리 정렬 (value 기준) sorted_by_value = sorted(d.items(), key=lambda x: x[1]) # [('a', 1), ('b', 2), ('c', 3)] sorted_by_value_desc = sorted(d.items(), key=lambda x: x[1], reverse=True) # [('c', 3), ('b', 2), ('a', 1)] # 튜플 리스트 정렬 data = [('apple', 5), ('banana', 2), ('cherry', 8)] sorted(data, key=lambda x: x[1]) # [('banana', 2), ('apple', 5), ('cherry', 8)] sorted(data, key=lambda x: x[0]) # [('apple', 5), ('banana', 2), ('cherry', 8)] # 복잡한 정렬 (여러 조건) students = [('Alice', 25, 90), ('Bob', 22, 85), ('Charlie', 25, 95)] sorted(students, key=lambda x: (x[1], -x[2])) # 나이 오름차순, 점수 내림차순 # 딕셔너리로 다시 변환 dict(sorted_by_value) # {'a': 1, 'b': 2, 'c': 3}
Python
복사

8. stack 사용법 (리스트로 구현)

# 스택 생성 (리스트 사용) stack = [] # 요소 추가 (push) stack.append(1) stack.append(2) stack.append(3) # [1, 2, 3] # 요소 제거 (pop) top = stack.pop() # 3 반환, stack은 [1, 2] # 최상단 요소 확인 (peek) if stack: top = stack[-1] # 2 (제거하지 않음) # 스택이 비어있는지 확인 is_empty = len(stack) == 0 is_empty = not stack # 더 간결한 방법 # 스택 크기 size = len(stack) # 전체 출력 print(stack) # [1, 2] # 스택 초기화 stack.clear() # [] # 예제: 괄호 검사 def is_valid_parentheses(s): stack = [] pairs = {'(': ')', '[': ']', '{': '}'} for char in s: if char in pairs: # 여는 괄호 stack.append(char) elif char in pairs.values(): # 닫는 괄호 if not stack or pairs[stack.pop()] != char: return False return len(stack) == 0 # collections.deque를 사용한 스택 (더 효율적) from collections import deque stack = deque() stack.append(1) # push stack.append(2) top = stack.pop() # pop top = stack[-1] # peek # 주의: deque는 양방향 큐이지만 스택으로도 사용 가능 # append()와 pop()만 사용하면 O(1) 스택 연산
Python
복사

9. tuple 사용법 (불변 시퀀스)

# 튜플 생성 t = (1, 2, 3) t = 1, 2, 3 # 괄호 생략 가능 t = (1,) # 요소가 하나일 때는 쉼표 필수 t = tuple([1, 2, 3]) # 리스트에서 변환 # 인덱싱과 슬라이싱 t = (10, 20, 30, 40, 50) t[0] # 10 t[-1] # 50 t[1:4] # (20, 30, 40) t[:3] # (10, 20, 30) t[::2] # (10, 30, 50) # 튜플 언패킹 t = (1, 2, 3) a, b, c = t # a=1, b=2, c=3 # 확장 언패킹 (Python 3+) t = (1, 2, 3, 4, 5) a, *b, c = t # a=1, b=[2,3,4], c=5 a, b, *c = t # a=1, b=2, c=[3,4,5] # 값 교환 (언패킹 활용) a, b = 1, 2 a, b = b, a # a=2, b=1 # 튜플 메서드 t = (1, 2, 3, 2, 4, 2) t.count(2) # 3 (2의 개수) t.index(3) # 2 (3의 인덱스) len(t) # 6 (길이) # 튜플 연산 t1 = (1, 2) t2 = (3, 4) t1 + t2 # (1, 2, 3, 4) (연결) t1 * 3 # (1, 2, 1, 2, 1, 2) (반복) # 포함 여부 확인 2 in t # True 5 in t # False # 튜플 정렬 (새 리스트 반환) t = (3, 1, 4, 1, 5) sorted(t) # [1, 1, 3, 4, 5] (리스트로 반환) tuple(sorted(t)) # (1, 1, 3, 4, 5) (다시 튜플로) # 최대/최소/합계 t = (3, 1, 4, 1, 5) max(t) # 5 min(t) # 1 sum(t) # 14 # 튜플 to 리스트, 리스트 to 튜플 t = (1, 2, 3) lst = list(t) # [1, 2, 3] t = tuple(lst) # (1, 2, 3) # 딕셔너리의 키로 사용 (리스트는 불가능) d = {} d[(1, 2)] = "value" # 가능 # d[[1, 2]] = "value" # 에러 (리스트는 불가능) # 함수에서 여러 값 반환 def get_coordinates(): return 10, 20 # 튜플로 반환 x, y = get_coordinates() # x=10, y=20 # enumerate와 함께 사용 arr = ['a', 'b', 'c'] for i, val in enumerate(arr): # enumerate는 (인덱스, 값) 튜플 생성 print(i, val) # 네임드 튜플 (collections.namedtuple) from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) p = Point(10, 20) p.x # 10 p.y # 20 p[0] # 10 (인덱스 접근도 가능) # 튜플 vs 리스트 # - 튜플: 불변(immutable), 빠름, 딕셔너리 키로 사용 가능 # - 리스트: 가변(mutable), 수정 가능, 더 많은 메서드
Python
복사

10. DFS / BFS

class Solution: def maxDepth(self, root: Optional[TreeNode]) -> int: if root is None: return 0 st = [(root, 1)] # 스택: (노드, 깊이) ans = 0 while st: node, depth = st.pop() ans = max(ans, depth) if node.left: st.append((node.left, depth + 1)) if node.right: st.append((node.right, depth + 1)) return ans
Python
복사
from typing import Optional from collections import deque class Solution: def maxDepth(self, root: Optional[TreeNode]) -> int: if root is None: return 0 q = deque([(root, 1)]) # 큐: (노드, 깊이) ans = 0 while q: node, depth = q.popleft() ans = max(ans, depth) if node.left: q.append((node.left, depth + 1)) if node.right: q.append((node.right, depth + 1)) return ans
Python
복사
from collections import deque from typing import List class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: if not grid or not grid[0]: return 0 m, n = len(grid), len(grid[0]) visited = [[False for _ in range(n)] for _ in range(m)] dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)] res = 0 for i in range(m): for j in range(n): if visited[i][j] or grid[i][j] == 0: continue q = deque([(i, j)]) visited[i][j] = True area = 0 while q: x, y = q.popleft() area += 1 for dx, dy in dirs: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n \ and not visited[nx][ny] and grid[nx][ny] == 1: visited[nx][ny] = True q.append((nx, ny)) res = max(res, area) return res
Python
복사