프로그래밍 언어 (Programming language)/파이썬 (Python)

타 언어 사용자의 파이썬 코딩 테스트를 위한 파이썬 총 정리 벼락치기

sobal 2026. 2. 3. 23:41

그 동안 C언어를 사용해 알고리즘 문제들을 풀었지만 이번 기업 코딩 테스트는 C언어로 볼 수 없어 파이썬을 하루 동안 벼락치기하게 되었다. 아무래도 단기간에 빠르게 익혀야하다보니 알고리즘 문제를 풀 수 있을만큼 필요한 부분만 뽑아서 정리해보았다.

자료형

기본 자료형

숫자형 - int(정수), float(실수), complex(복소수)

문자열 - str

불리언 - bool

 

컨테이너 자료형

리스트(list), 튜플(tuple), 딕셔너리(dictionary), 집합(set)

- int, float, str, bool

 

기초 문법

주석

한 줄 주석 - #

여러 줄 주석 - ''' ''', """ """"

 

슬라이싱

기본 형태 - seq[start : stop : step]

예시 :

s[:]        # 전체 복사(얕은 복사)
s[::-1]     # 역순
s[::2]      # 짝수 인덱스(0,2,4,...)만
s[1::2]     # 홀수 인덱스(1,3,5,...)만
s[:n]       # 앞 n개
s[n:]       # n부터 끝까지
s[:-1]      # 마지막 빼고
s[1:-1]     # 양 끝 제거


연산자

산술 연산자 - +(덧셈), -(뺄셈), *(곱셈), /(나눗셈), //(몫), %(나머지), **(거듭제곱), @(행렬 곱)

단항 연산자 - +(부호 유지), -(부호 반전)

비트 연산자 - ~(NOT), <<(쉬프트), >>(쉬프트), &(AND), ^(XOR), |(OR)

비교 연산자 - <, <=, >, >=, ==, !=

논리 연산자 - and, or, not

멤버 연산자 - in, not in

 

형변환

int(), float(), str(), bool()(0 이거나 값이 없으면 false)

 

문자열 처리

합치기 - snack = '스윙칩', one = '1개' > giveme = one + snack, giveme = one + '스윙칩'

길이 - len()

여러줄 문자

icecream = ''' 올 때
메로나
사오세요'''

icecream = """ 올 때
메로나
사오세요"""

반복출력

print('-' *20) # 출력 결과 : --------------------

 

문자열 메소드

이름 분류 시그니처 핵심 기능 반환
lower() 대소문자 s.lower() 대문자→소문자 새 문자열 
upper() 대소문자 s.upper() 소문자→대문자 새 문자열 
capitalize() 대소문자 s.capitalize() 첫 글자만 대문자(제목 케이스), 나머지 소문자 새 문자열 
title() 대소문자 s.title() 각 “단어”의 첫 글자 대문자 새 문자열 
swapcase() 대소문자 s.swapcase() 대↔소문자 상호 변환 새 문자열 
split() 분리 s.split(sep=None, maxsplit=-1) 구분자로 문자열을 쪼개 리스트 생성 list[str] 
count() 검색 s.count(sub[, start[, end]]) 부분문자열 (겹치지 않게) 등장 횟수 int 
find() 검색 s.find(sub[, start[, end]]) 부분문자열의 첫 위치 인덱스, 없으면 -1 int 
startswith() 접두사 s.startswith(prefix[, start[, end]]) 접두사면 True (튜플 가능) bool 
endswith() 접미사 s.endswith(suffix[, start[, end]]) 접미사면 True (튜플 가능) bool 
strip() 공백/문자 제거 s.strip(chars=None) 양쪽 끝 문자 제거(기본: 공백) 새 문자열 
replace() 치환 s.replace(old, new, count=-1) old→new 치환(앞에서 count개만 가능) 새 문자열 
center() 정렬/패딩 s.center(width, fillchar=' ') 가운데 정렬 + 채움문자 패딩 새 문자열(또는 원본) 

 

문자열 포맷과 탈출 문자

f-string

  • 문자열 앞에 f 붙이고 {} 안에 변수/ 표현식을 넣어 치환
  • { 또는 }를 그대로 출력하려면 {{ / }} 처럼 두 번 써야 함.
  • f-string의 { ... } 표현식 내부에는 백슬래시(\)를 직접 쓸 수 없음(예: 따옴표 이스케이프용). 이런 경우 따옴표 종류를 바꾸거나(싱글/더블), 문자열 부분에서 처리
name = "Kim"
score = 91.2345

s1 = f"Hello, {name}"
s2 = f"score={score:.2f}"        # 소수 2자리
s3 = f"2+3={2+3}"                # 표현식 가능

por = '포르쉐'
hyu = '현대'

printf(f'저는 {por},{hyu} 등이 있어요.')

 

str.format()

  • 치환 필드 문법 : {field_name!conversion:format_spec}
"Coordinates: {latitude}, {longitude}".format(latitude="37.24N", longitude="-115.81W")
"{:<10} | {:>10}".format("left", "right")   # 정렬
"{:,}".format(1234567890)                   # 천 단위 구분

por = '포르쉐'
hyu = '현대'
printf('저는 {1},{0} 등이 있어요.'.format(hyu,por))

 

탈출 문자

표기 의미
\\ 백슬래시 자체
\' / \" 따옴표 자체
\n 줄바꿈 (newline)
\t 탭 (tab)
\r 캐리지 리턴 (CR)
\b 백스페이스
\f 폼피드
\v 수직 탭
\xhh 16진수 바이트 값(2자리)
\uXXXX 유니코드(16진수 4자리)
\UXXXXXXXX 유니코드(16진수 8자리)
\N{name} 이름으로 유니코드 지정

 

리스트 메소드

이름 형태 동작 반환
append(x) a.append(x) 맨 뒤에 x 추가 None
extend(iterable) a.extend(it) 여러 요소를 뒤에 이어붙임 None
insert(i, x) a.insert(i, x) 인덱스 i 위치에 x 삽입 None
remove(x) a.remove(x) 값이 x인 첫 요소 삭제(없으면 에러) None
pop([i]) a.pop() / a.pop(i) 인덱스 i(기본: 마지막) 요소 삭제 + 반환 요소 1개
clear() a.clear() 모든 요소 삭제 None
index(x[, start[, end]]) a.index(x, ...) x의 첫 위치 인덱스(없으면 에러) int
count(x) a.count(x) x 등장 횟수 int
sort(*, key=None, reverse=False) a.sort(...) 리스트를 제자리 정렬 None
reverse() a.reverse() 순서를 제자리에서 뒤집음 None
copy() a.copy() 얕은 복사(a[:]와 동치) 새 list

 

튜플 메소드

이름 형태 의미 반환 주의
count(value) t.count(x) 튜플 안에서 x가 몇 번 등장하는지(전체 발생 횟수) int 겹침 개념 없음(원소 단위 카운트)
index(value[, start[, stop]]) t.index(x) / t.index(x, start) / t.index(x, start, stop) x가 처음 등장하는 위치(인덱스) int 없으면 ValueError. start/stop 범위 내에서만 찾음(슬라이싱처럼 stop은 제외)

세트 메소드

원본 유지

이름 형태 동작 반환
isdisjoint(other) s.isdisjoint(o) 교집합이 비어있으면 True bool
issubset(other) s.issubset(o) 부분집합 여부 (s <= o) bool
issuperset(other) s.issuperset(o) 상위집합 여부 (s >= o) bool
union(*others) s.union(o1, o2...) 합집합 (`s other`)
intersection(*others) s.intersection(...) 교집합 (s & other) 새 set
difference(*others) s.difference(...) 차집합 (s - other) 새 set
symmetric_difference(other) s.symmetric_difference(o) 대칭차 (s ^ other) 새 set
copy() s.copy() 얕은 복사 새 set

 

원본 변화

이름 형태 동작 반환
add(x) s.add(x) 원소 추가 None
remove(x) s.remove(x) 원소 삭제(없으면 KeyError) None
discard(x) s.discard(x) 원소 삭제(없어도 에러 없음) None
pop() s.pop() 임의 원소 1개 삭제+반환(비면 KeyError) 원소 1개
clear() s.clear() 전부 삭제 None
update(*others) s.update(...) 합집합으로 갱신 (`s = ...`)
intersection_update(*others) s.intersection_update(...) 교집합으로 갱신 (s &= ...) None
difference_update(*others) s.difference_update(...) 차집합으로 갱신 (s -= ...) None
symmetric_difference_update(other) s.symmetric_difference_update(o) 대칭차로 갱신 (s ^= o) None

 

딕셔너리 메소드

이름 형태 동작 반환
clear() d.clear() 모든 항목 삭제 None
copy() d.copy() 얕은 복사 새 dict
fromkeys(iterable, value=None) dict.fromkeys(keys, v) keys로 새 dict 생성(값은 동일 객체 참조 주의) 새 dict
get(key, default=None) d.get(k, def) key 없으면 default 반환(에러 안 냄)
keys() d.keys() key 뷰(view) view
values() d.values() value 뷰(view) view
items() d.items() (key,value) 뷰(view) view
pop(key[, default]) d.pop(k[, def]) key 삭제+값 반환(없으면 default 또는 KeyError)
popitem() d.popitem() 마지막에 넣은 항목(LIFO) 삭제+반환(비면 KeyError) (k, v)
setdefault(key, default=None) d.setdefault(k, def) 없으면 k:def 삽입 후 값 반환
update(...) d.update(...) 매핑/쌍(iterable)/kwargs로 갱신(덮어씀) None

 

tuple / list / set / dict 자료형 변환

공통 생성자(컨테이너 생성)

  • list(x) : x를 순회(iterate)해서 요소들을 리스트
  • tuple(x) : x를 순회해서 요소들을 튜플
  • set(x) : x를 순회해서 요소들을 셋으로 (중복 제거)
  • dict(x) : x를 순회해서 (key, value) 쌍으로 해석해 딕셔너리로

순서/중복/제약

  • list/tuple: 순서 유지, 중복 허용
  • set: 중복 제거, (수학적 집합) “동일 값 1개만”, 순서 개념은 기대하지 않는 게 안전
  • dict: 키 중복 불가(마지막 값이 덮어씀), 키는 hashable(불변)이어야 함

기본 컨테이너 ↔ 기본 컨테이너 변환

 

(1) list ↔ tuple

t = tuple([1, 2, 2])      # (1, 2, 2)
lst = list((1, 2, 2))     # [1, 2, 2]

(2) list/tuple → set

set([1, 2, 2])      # {1, 2}
set((1, 2, 2))      # {1, 2}

(3) set → list/tuple

list({3, 1, 2})     # 예: [1, 2, 3] 처럼 보일 수도 있지만 순서를 보장하지 않음
tuple({3, 1, 2})    # ( ... ) 역시 마찬가지

정렬된 결과가 필요하면:

sorted_list = sorted({3, 1, 2})  # [1, 2, 3]

 

 

dict 관련 변환(가장 헷갈리는 구간)

 

(1) dict → list / tuple / set : 

list(d) / tuple(d) / set(d) 는 기본적으로 키(keys) 를 순회

d = {"a": 1, "b": 2}

list(d)      # ['a', 'b']   (키)
tuple(d)     # ('a', 'b')
set(d)       # {'a', 'b'}

원하는 대상에 따라 다음을 사용:

list(d.keys())    # ['a', 'b']
list(d.values())  # [1, 2]
list(d.items())   # [('a', 1), ('b', 2)]

 

(2) list/tuple/set → dict : “(key, value) 쌍”

  • 아래처럼 길이 2짜리 iterable의 iterable 이어야 함.
pairs = [("a", 1), ("b", 2)]
dict(pairs)  # {'a': 1, 'b': 2}
  • 키 중복이면 마지막이 덮어씀
dict([("a", 1), ("a", 99)])  # {'a': 99}
  • 형태가 안 맞으면 오류
dict(["ab", "cd"])   # ValueError: 요소 길이가 2가 아님(문자열은 글자 단위로 쪼개짐)
dict([("a", 1, 2)])  # ValueError

 

(3) dict의 “키만/값만”으로 dict를 만들고 싶을 때

  • 키만 있고 값은 기본값을 넣고 싶으면 dict.fromkeys
dict.fromkeys(["a", "b"], 0)  # {'a': 0, 'b': 0}
  • 값이 가변 객체면(예: []) 모든 키가 같은 객체를 공유하니 주의
d = dict.fromkeys(["a", "b"], [])
d["a"].append(1)
# {'a': [1], 'b': [1]}  # 둘 다 같이 바뀜 (같은 리스트 공유)

 

 

문자열/바이트 같은 “iterable”에서의 변환 주의점

 

문자열은 글자 단위로 순회됨.

list("abc")     # ['a', 'b', 'c']
set("aba")      # {'a', 'b'}
tuple("ab")     # ('a', 'b')

dict("ab") 는 시도하면 각 글자(요소)가 길이 2의 (k,v)가 아니라서 보통 오류가 남.
(원리상 dict(x)는 x의 각 원소가 (k, v)여야 함)

 

List Comprehension

형태 : new_list = [변수 활용 for 변수 in 반복대상 if 조건]

예시 :

# 기본 변환
nums = [1, 2, 3, 4, 5]
squares = [x * x for x in nums]
# [1, 4, 9, 16, 25]

# 조건 필터링
nums = [1, 2, 3, 4, 5, 6]
evens = [x for x in nums if x % 2 == 0]
# [2, 4, 6]

# if-else 포함
nums = [1, 2, 3, 4, 5]
labels = ["even" if x % 2 == 0 else "odd" for x in nums]
# ['odd', 'even', 'odd', 'even', 'odd']

# 중첩 루프
pairs = [(i, j) for i in [1, 2, 3] for j in [10, 20]]
# [(1, 10), (1, 20), (2, 10), (2, 20), (3, 10), (3, 20)]

# 문자열 처리
words = ["hi", "python", "a", "list"]
result = [w.upper() for w in words if len(w) >= 2]
# ['HI', 'PYTHON', 'LIST']

# 2차원 리스트 펼치기
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in matrix for x in row]
# [1, 2, 3, 4, 5, 6]

# 공백 제거 빈 문자열 제거
raw = ["  apple ", " ", " banana", "", "cherry  "]
clean = [s.strip() for s in raw if s.strip()]
# ['apple', 'banana', 'cherry']

 

for 문 

  • iterable(리스트/튜플/문자열/딕트/제너레이터 등) 을 순회하며 요소를 꺼냄.
  • 기본 형태
for x in iterable:
    ...
  • 자주 쓰는 패턴
    • 인덱스 필요: enumerate(iterable)
    • 여러 개 묶기: zip(a, b)
    • 반복 횟수: range(n)
    • 반복 중단/건너뜀: break / continue
    • for-else: break 없이 끝까지 돌면 else 실행
    • range의 경우 형식은 range(start, stop,step)
for x in items:
    if cond: break
else:
    # break가 없었을 때만
    ...

 

 

if 문 (조건 분기)

  • 조건은 truthy/falsey로 평가됨. (0, "", [], {}, None 등은 보통 falsey)
  • 기본 형태
if cond:
    ...
elif other_cond:
    ...
else:
    ...
  • 자주 쓰는 표현
    • 삼항 연산: a if cond else b
    • 단락 평가: A and B, A or B
    • 비교 연쇄: 0 < x < 10

while 문 (조건 반복)

  • 조건이 True인 동안 반복.
  • 기본 형태
while cond:
    ...
  • 무한 루프는 while True: + 종료 조건에서 break
  • while-else: break 없이 조건이 False가 되어 종료되면 else 실행
while cond:
    if stop: break
else:
    ...

 

함수 def

정의/호출

def f(a, b=0, *args, **kwargs):
    return a + b

 

핵심 포인트

  • return 없으면 None 반환
  • 기본 인자(default)는 함수 정의 시점에 평가됨 -> 가변 객체([], {}) 기본값은 주의
def bad(x, acc=[]):  # 지양
    acc.append(x)
    return acc
  • 스코프: 지역/전역, 필요 시 global, nonlocal
  • 람다: lambda x: x+1 (간단한 익명 함수)

함수에서 가변인자 활용(*)

주문 합계 계산: *items = “몇 개가 오든 다 받기”

def total_price(order_id, *items):
    # order_id: 고정 인자 1개
    # items: order_id 뒤에 오는 모든 위치 인자들을 튜플로 묶음
    print("order_id:", order_id)
    print("items:", items, type(items))  # 튜플 확인
    return sum(items)

print(total_price("A001", 3000))                 # 1개 상품
print(total_price("A002", 3000, 1200, 500))      # 3개 상품
  • 호출 시 내부에서 실제로 매핑되는 값( *items는 “뒤에 붙는 위치 인자들을 전부 모아 튜플로 만듦)
    • total_price("A001", 3000)
      • order_id = "A001"
      • items = (3000,) ← 튜플(원소 1개)
    • total_price("A002", 3000, 1200, 500)
      • order_id = "A002"
      • items = (3000, 1200, 500) ← 튜플(원소 3개)

리스트를 풀어서 전달(언패킹)

prices = [3000, 1200, 500]
print(total_price("A003", *prices))
  • *prices는 리스트를 원소 단위로 펼쳐서 인자로 전달
  • 결과적으로 items = (3000, 1200, 500)가 된다.
  • 함수 정의에서 *items : 모으기(pack)
  • 함수 호출에서 *prices : 풀기(unpack)

인자 배치 규칙

def f(a, b, *rest):
    ...
  • a, b는 필수(고정) 위치 인자
  • rest는 그 뒤에 남는 모든 위치 인자
f(1, 2)            # rest = ()
f(1, 2, 3, 4, 5)   # rest = (3, 4, 5)
  • 또 중요한 규칙 하나:
  • *rest는 항상 위치 인자들 중 마지막 수집용이라서 뒤에 또 다른 일반 위치 인자를 둘 수 없음
    (단, * 뒤에 키워드 전용 인자는 가능)

try 예외 처리

  • 기본 형태
try:
    #수행 문장
except:
    #에러 발생 시 수행 문장
else:
    #에러 없을 시 수행 문장
    ...
finally:
    #무관하게 마지막에 항상 수행하는 문장
    ...
  • 핵심 포인트
    • 구체적인 예외 타입을 잡는 게 원칙 (except Exception:은 최후 수단)
    • 예외 발생시키기: raise ValueError("msg")
    • 자원 해제는 보통 with(context manager) 사용이 더 안전함.
    • except과 finally 중 하나는 있어야함

class (객체/상태/행동 캡슐화)

  • 기본 형태
class A:
    def __init__(self, x):
        self.x = x

    def inc(self):
        self.x += 1
  • 핵심 포인트
    • self: 인스턴스 자신
    • 인스턴스 변수: self.x
    • 클래스 변수: A.shared (모든 인스턴스가 공유)
    • 메서드 종류
      • 인스턴스 메서드: def m(self, ...)
      • 클래스 메서드: @classmethod def m(cls, ...)
      • 정적 메서드: @staticmethod def m(...)
    • 상속: class B(A): ..., 오버라이드/super()

파일 입출력

open() 기본 형태와 의미

f = open("list.txt", "r", encoding="utf-8")
  • 파일명(path): "list.txt" (상대경로/절대경로 가능)
  • 열기 모드(mode): "r", "w", "a" 등
  • encoding: 텍스트 파일을 문자로 읽고/쓸 때 인코딩 지정(한글 포함이면 보통 utf-8 권장)
  • open()은 파일 객체(file object) 를 반환하고, 이 객체로 read(), write() 등을 수행

열기 모드(mode) 

(1) r (read, 읽기)

  • 파일이 없으면 오류(FileNotFoundError)
  • 읽기만 가능
with open("list.txt", "r", encoding="utf-8") as f:
    contents = f.read()
    print(contents)

 

(2) w (write, 쓰기)

  • 파일이 없으면 새로 생성
  • 파일이 있으면 기존 내용을 전부 지우고(초기화) 덮어씀
with open("list.txt", "w", encoding="utf-8") as f:
    f.write("김xx\n")
    f.write("정xx\n")
    f.write("허xx\n")

 

(3) a (append, 이어서 쓰기)

  • 파일이 없으면 새로 생성
  • 파일이 있으면 맨 뒤에 이어서 추가
with open("list.txt", "a", encoding="utf-8") as f:
    f.write("추가된줄\n")

 

 

파일 쓰기(write)

 

write()는 “문자열”을 쓴다

  • \n을 직접 넣어야 줄바꿈이 된다.
with open("list.txt", "w", encoding="utf-8") as f:
    f.write("첫 줄\n")
    f.write("둘째 줄\n")

 

여러 줄을 한 번에 쓰기

lines = ["A\n", "B\n", "C\n"]
with open("list.txt", "w", encoding="utf-8") as f:
    f.writelines(lines)   # 리스트(반복가능객체) 그대로 이어서 씀

 

 

파일 읽기(read) 

(1) read() : 파일 전체를 한 번에 문자열로

with open("list.txt", "r", encoding="utf-8") as f:
    contents = f.read()
    print(contents)
  • 파일이 크면 메모리 사용이 커질 수 있음

(2) readline() : 한 줄씩 읽기

with open("list.txt", "r", encoding="utf-8") as f:
    line = f.readline()   # 한 줄(끝에 \n 포함 가능)

(3) for line in f: 

with open("list.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line, end="")   # end=""는 아래 설명 참고

 

close() vs with open(...) as f:

 

직접 열고 닫기

f = open("list.txt", "r", encoding="utf-8")
print(f.read())
f.close()

 

with 문(컨텍스트 매니저)

with open("list.txt", "r", encoding="utf-8") as f:
    print(f.read())
# 블록을 벗어나면 자동으로 close()
  • 예외가 발생해도 파일이 안전하게 닫힘

자주 같이 알아두는 모드 옵션

  • "x": 새로 생성 전용(이미 파일 있으면 오류)
  • "b": 바이너리 모드(이미지/zip 등) -> 예: "rb", "wb"
  • "t": 텍스트 모드(기본값) -> 예: "rt", "wt"
  • "r+", "w+", "a+": 읽기+쓰기 (동작이 헷갈릴 수 있어 필요할 때만)

예시)

with open("img.png", "rb") as f:
    data = f.read()

 

self와 상속(Inheritance) 

self

  • 파이썬에서 클래스 메서드는 항상 첫 번째 인자로 self를 받음
  • self는 메서드를 호출한 인스턴스 객체
  • 메서드 안에서 인스턴스 변수(멤버 변수)에 접근할 때 self.변수명 형태를 사용

예시:

class SmartWatch:
    def __init__(self, model, price):
        self.model = model
        self.price = price

    def start_timer(self, minutes):
        print(f"{self.model}: 타이머 {minutes}분 시작")

 

사용 예

w1 = SmartWatch("A-Watch", 199000)
w2 = SmartWatch("B-Watch", 149000)

w1.start_timer(10)  # A-Watch: 타이머 10분 시작
w2.start_timer(5)   # B-Watch: 타이머 5분 시작


아래 두 코드는 같은 의미

w1.start_timer(10)
SmartWatch.start_timer(w1, 10)

 

 

상속(Inheritance) 

 

상속은 기존 클래스를 기반으로 기능을 추가/변경해 새 클래스를 만드는 방식

  • 부모 클래스(Parent/Base class): 기본 기능 제공
  • 자식 클래스(Child/Derived class): 부모 기능을 물려받고, 필요한 기능을 추가

예시: GPS 기능이 있는 스마트워치(자식 클래스)

class GPSWatch(SmartWatch):
    def start_gps(self):
        print(f"{self.model}: GPS 추적 시작")

사용 예

w_basic = SmartWatch("A-Watch", 199000)
w_gps   = GPSWatch("A-Watch Pro", 249000)

# w_basic.start_gps()  # SmartWatch에는 start_gps가 없으므로 에러
w_gps.start_gps()      # A-Watch Pro: GPS 추적 시작

 

super()로 부모 생성자(__init__) 재사용

  • 자식 클래스가 부모의 속성 초기화 로직을 그대로 쓰고, 자기만의 속성을 추가하고 싶다면 super().__init__()를 사용

예시: 배터리 용량(battery)을 추가한 GPSWatch

class GPSWatch(SmartWatch):
    def __init__(self, model, price, battery):
        super().__init__(model, price)  # 부모 초기화 재사용
        self.battery = battery          # 자식 속성 추가

    def start_gps(self):
        print(f"{self.model}: GPS 추적 시작 (배터리 {self.battery}%)")

 

사용 예

w = GPSWatch("A-Watch Pro", 249000, 80)
w.start_gps()
# A-Watch Pro: GPS 추적 시작 (배터리 80%)

 

 

오버라이딩(Overriding)

  • 자식 클래스가 부모 메서드의 동작을 바꾸거나 확장하고 싶을 때 같은 메서드 이름으로 다시 정의

 

예시: 타이머 시작 시 GPS 기록도 자동으로 켜기(기능 확장)

class AdvancedGPSWatch(GPSWatch):
    def start_timer(self, minutes):  # 부모의 start_timer를 재정의(오버라이딩)
        print(f"{self.model}: 타이머 {minutes}분 시작")
        self.start_gps()             # 추가 동작(확장)

 

사용 예

w = AdvancedGPSWatch("A-Watch Ultra", 299000, 90)
w.start_timer(20)
# A-Watch Ultra: 타이머 20분 시작
# A-Watch Ultra: GPS 추적 시작 (배터리 90%)

 

 

다중 상속(Multiple Inheritance) 

 

  • 파이썬은 한 클래스가 여러 부모 클래스를 동시에 상속할 수 있음

 

예시: 운동 기록 기능 + 알림 전송 기능을 조합

class WorkoutRecorder:
    def record(self):
        print("운동 기록 저장 완료")

class Notifier:
    def send(self):
        print("알림 전송 완료")

class FitnessWatch(GPSWatch, WorkoutRecorder, Notifier):
    pass

 

사용 예

fw = FitnessWatch("Fit-Watch", 219000, 70)
fw.start_gps()  # GPSWatch에서 상속
fw.record()     # WorkoutRecorder에서 상속
fw.send()       # Notifier에서 상속

 

 

pass

  • 아무 동작도 하지 않고 자리만 채우는 문장
  • 문법적으로 블록이 필요한데 아직 구현할 내용이 없을 때 사용

 

클래스/메서드에서 pass

class Device:
    def start(self):
        pass  # 나중에 구현

 

반복문/조건문에서 pass

for _ in range(3):
    pass

if 10 > 3:
    pass

# while True:
#     pass  # 무한 루프가 되므로 주의

 

 

Import

import 모듈

 

모듈(module)

  • 파이썬에서 하나의 .py 파일 == 모듈
  • message.py라는 파일을 만들면, 이 파일의 모듈 이름은 message

message.py

def hello():
    print("안녕하세요")

 

 

import 모듈

  • 모듈 전체를 가져오는 방식

main.py

import message

message.hello()

 

 

필요한 것만 import: from 모듈 import 함수/변수/클래스

  • 모듈 안에서 원하는 것만 가져오는 방식

main.py

from message import hello

hello()
  • 표준 라이브러리 예시: random.choice
  • 표준 라이브러리도 동일하게 import해서 사용
import random

menu = ["김치찌개", "된장찌개", "제육볶음"]
print(random.choice(menu))
  • random.choice(리스트)는 리스트에서 무작위 원소 1개를 뽑음

 

패키지(package)

  • 모듈들을 묶어둔 폴더라고 보면 된다.

예시)

project/
  app.py
  utils/
    formatter.py
    notifier.py
  • utils : 패키지(폴더)
  • formatter.py, notifier.py : 모듈(파일)

utils/formatter.py

def pretty(text):
    return f"[INFO] {text}"

 

utils/notifier.py

def send():
    print("알림 전송 완료")

 

  • 패키지 경로 import: import 패키지.모듈
  • 점(.)으로 경로를 이어서 가져올 수 있다.
  • 이렇게 하면 호출도 utils.formatter.pretty(...)처럼 경로를 끝까지 써야 함

app.py

import utils.formatter

msg = utils.formatter.pretty("서버 시작")
print(msg)

 

  • 패키지에서 모듈만 가져오기: from 패키지 import 모듈

 

app.py

from utils import notifier

notifier.send()

 

  • 모듈 안에서 특정 함수만 가져오기
from utils.formatter import pretty

print(pretty("데이터 로드 완료"))

 

코테에서의 기본 입출력 방식

시간 단축용 기본 세팅: 빠른 입력 함수로 바인딩

import sys
input = sys.stdin.readline
  • 이후 input() 호출이 곧 sys.stdin.readline()
  • 간단한 숫자 입력은 보통 int(input())로 충분

입력 패턴 모음

 

정수 1개

n = int(input())

 

한 줄에 정수 여러 개

a, b, c = map(int, input().split())

 

여러 줄에 정수 T개

t = int(input())
arr = [int(input()) for _ in range(t)]

 

문자열 한 줄 (개행 제거 필요할 때)

  • readline()은 보통 끝에 \n이 붙으니 문자열은 아래처럼:
s = input().rstrip()   # 오른쪽(끝) 공백/개행만 제거 (보통 strip보다 안전)
  • rstrip() 쓰는 이유: strip()은 왼쪽 공백까지 지워서 의도치 않게 데이터가 바뀔 수 있음
  • 예: " abc"를 입력으로 쓰는 문제에서 strip()은 위험

EOF(입력 끝)까지 계속 읽기 (테스트케이스 개수 미제공)

while True:
    line = sys.stdin.readline()
    if not line:        # EOF면 빈 문자열이 옴
        break
    x = int(line)
    # 처리...

 

또는 sys.stdin 자체를 순회:

for line in sys.stdin:
    x = int(line)
    # 처리...

 

 

출력 패턴 모음

 

한 줄 출력 (print 대신 write)

sys.stdout.write(str(ans) + "\n")
  • write()는 개행 자동 없음 → \n 직접 추가

여러 줄 출력 (가장 자주 쓰는 고속 패턴: join)

out = []
for _ in range(t):
    out.append(str(result))
sys.stdout.write("\n".join(out))
  • print()를 t번 호출하는 것보다 빠름
  • 출력이 많을수록 차이가 큼

공백으로 구분해 한 줄에 출력

out = [1, 2, 3]
sys.stdout.write(" ".join(map(str, out)) + "\n")

 

 

자주 쓰는 “입력+출력” 조합 예시

T개 입력 → T개 결과 출력

import sys
input = sys.stdin.readline

t = int(input())
out = []

for _ in range(t):
    n = int(input())
    out.append(str(n * 2))

sys.stdout.write("\n".join(out))

 

n, m 한 줄 입력 + 이후 n줄 배열 입력

import sys
input = sys.stdin.readline

n, m = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]

# 예시 처리
sys.stdout.write(str(sum(map(sum, grid))) + "\n")

 

EOF까지 “여러 테스트케이스”

import sys

out = []
for line in sys.stdin:
    x = int(line)
    out.append(str(x + 1))

sys.stdout.write("\n".join(out))

 

 

기본 템플릿

import sys
input = sys.stdin.readline

# 입력
t = int(input())
out = []

for _ in range(t):
    # 처리
    n = int(input())
    out.append(str(n))  # 결과 저장

# 출력
sys.stdout.write("\n".join(out))

 

 

코테에서 기억해야할 모듈 및 모듈 함수

 

sys (빠른 입출력)

import sys
input = sys.stdin.readline

n = int(input())  # 한 줄 정수

# 여러 줄 출력 (out은 문자열 리스트)
out = ["1", "2", "3"]
sys.stdout.write("\n".join(out))

 

 

collections.deque (BFS / 큐)

from collections import deque

q = deque()
q.append(1)        # 뒤에 넣기
q.append(2)
x = q.popleft()    # 앞에서 빼기 (큐)
print(x)           # 1

 

 

collections.Counter (빈도 세기)

from collections import Counter

arr = [1, 1, 2, 3, 3, 3]
cnt = Counter(arr)
print(cnt[3])      # 3이 몇 번? -> 3

 

 

collections.defaultdict (기본값 dict)

from collections import defaultdict

d = defaultdict(int)   # 없는 키는 기본값 0
d["a"] += 1
d["a"] += 1
print(d["a"])          # 2

 

 

heapq (우선순위 큐 / 최소 힙)

import heapq

h = []
heapq.heappush(h, 5)
heapq.heappush(h, 2)
heapq.heappush(h, 7)

print(heapq.heappop(h))  # 가장 작은 값 -> 2

 

최대 힙(큰 값 우선)은 음수로:

import heapq

h = []
heapq.heappush(h, -10)
heapq.heappush(h, -3)
print(-heapq.heappop(h))  # 10

 

 

bisect (이분 탐색 / 삽입 위치)

from bisect import bisect_left, bisect_right

arr = [1, 2, 2, 4]
print(bisect_left(arr, 2))   # 2가 처음 등장하는 위치 -> 1
print(bisect_right(arr, 2))  # 2가 끝난 다음 위치 -> 3

 

 

math (수학 함수)

from math import gcd, lcm, isqrt

print(gcd(12, 18))  # 6
print(lcm(4, 6))    # 12
print(isqrt(10))    # 3 (정수 제곱근)

 

 

itertools (조합/순열/누적합)

from itertools import combinations, permutations, product, accumulate

print(list(combinations([1, 2, 3], 2)))   # (1,2) (1,3) (2,3)
print(list(permutations([1, 2, 3], 2)))   # (1,2) (1,3) (2,1) ...
print(list(product([0, 1], repeat=3)))    # 3자리 이진 모든 경우
print(list(accumulate([1, 2, 3])))        # [1, 3, 6]

 

 

functools.lru_cache (재귀 DP 메모이제이션)

from functools import lru_cache

@lru_cache(None)
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(30))

 

 

re (정규표현식: 숫자 뽑기/파싱)

import re

s = "a-12 b34"
nums = list(map(int, re.findall(r"-?\d+", s)))
print(nums)  # [-12, 34]

 

이렇게 정리한 걸 머리 속에 집어넣고 백준에서 알고리즘 문제 그래프 파트 전까 한 바퀴 돌리면 실버 이하의 문제 정도는 대비할 수 있지 않을까 싶다.

반응형