파이썬 기초 다지기 4

류한선·2025년 7월 5일

실기연습-2

목록 보기
91/95

맞아! 아까 우리가 다룬 건 1번부터 15번까지, 기본기 + 실전에서 자주 쓰이지만 처음 보면 헷갈리는 문법/구조들이었어.
하지만 그 외에도 정보처리기사 실기 수준 또는 조금만 난이도 올라가면 반드시 알아야 하는 파이썬 핵심 문법꽤 더 있어.


✅ 지금까지 배운 1~15번은?

번호주제핵심 포인트
1~2리스트 컴프리헨션간결한 반복문
3~5enumerate, zip 등반복문과 함께 사용
6~8람다, map, filter함수형 문법
9** (제곱, 언팩)두 가지 쓰임
10*args, **kwargs가변 인자
11try-except예외 처리
12heapq, itertools, collections자주 쓰이는 모듈
13is vs ==비교 트랩
14in 연산자동작 방식 자료형별 다름
15list vs set vs dict내부 구조 비교

✅ 그럼 이제 질문: 그 외에도 꼭 알아야 할 건 뭐야?

➡ 아래는 정보처리기사 실기 + 알고리즘 문제 + 파이썬 중급 레벨에서
거의 필수로 자주 튀어나오는 핵심 문법들이야.
우리가 16번 이후로 이어가면 좋을 주제들이기도 해.


✅ 추천 필수 문법/개념 목록 (16번 이후로 배울만한 것들)

번호주제왜 중요한가?
16sorted() vs sort()리턴 차이로 자주 실수함
17copy() vs deepcopy()얕은 복사 트랩
18리스트 슬라이싱 [:]참조 vs 복사 헷갈림
19defaultdict, Counter카운팅 문제의 왕
20reversed(), [::-1]리스트 뒤집기 차이
21문자열 처리 함수strip(), split(), join()
22yield와 제너레이터메모리 효율형 반복자
23any(), all()조건 검사에 깔끔하게 사용
24with open()파일 입출력은 실기 기본
25클래스와 __init__구조화된 데이터 처리용

✅ 그 외에도 실기 대비로 필요한 것들

주제설명
파이썬 자료형 별 시간복잡도set, dict, list 각각 어떤 연산이 빠른지
순열/조합/백트래킹 직접 구현itertools 없이도 구현할 줄 알아야 함
입출력 속도 처리 (sys.stdin.read)대량 입력에서 필수
객체의 참조, 얕은 복사 vs 깊은 복사실기에서 리스트 변경 트랩 자주 나옴

✅ 정리하자면

  • 우리가 배운 1~15번은 필수 기본기 + 실기 실수 트랩이었고,
  • 이 외에도 16번~25번쯤 되는 **"한 단계 올라간 핵심 문법들"**이 더 있어.
  • 이걸 알면 정보처리기사 실기 문제 대부분을 파이썬으로 정확히 해석하고 디버깅할 수 있어.

좋아! 이제 16번부터 20번까지, 실전에서 자주 나오는 파이썬 문법들을 1줄씩 완전히 해부해서
왜 헷갈리는지, 어떻게 써야 맞는지, 실수하면 어디서 터지는지까지 아주 천천히 설명해줄게.


✅ 16. sort() vs sorted() 차이 (리스트 정렬 트랩)


🔸 sort() — 원본 리스트를 정렬 (제자리 변경)

a = [3, 1, 2]
a.sort()
print(a)  # [1, 2, 3]

📌 a.sort()원본 리스트 자체를 바꿔버림, 리턴값은 None


🔸 sorted() — 새로운 리스트로 정렬

a = [3, 1, 2]
b = sorted(a)
print(a)  # [3, 1, 2]
print(b)  # [1, 2, 3]

📌 sorted(a)새로운 정렬된 리스트를 반환함. 원본은 그대로!


🔥 실전 트랩

a = [3, 1, 2]
b = a.sort()
print(b)  # ❌ None

👉 b = a.sort()는 항상 None이니까 주의!
→ 정렬된 리스트가 필요하면 sorted(a) 써야 함


✅ 요약

함수원본 변경?리턴값사용 위치
sort()✅ 바뀜None리스트 전용
sorted()❌ 안 바뀜새 리스트모든 반복형 자료 가능

✅ 17. copy() vs deepcopy() (복사 트랩)


🔸 얕은 복사 (copy())

import copy

a = [[1, 2], [3, 4]]
b = copy.copy(a)

b[0][0] = 99
print(a)  # [[99, 2], [3, 4]]

➡ 바깥 리스트만 복사하고, 내부 리스트는 여전히 같은 객체를 참조함


🔸 깊은 복사 (deepcopy())

import copy

a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)

b[0][0] = 99
print(a)  # [[1, 2], [3, 4]]

➡ 내부까지 완전히 새로운 복사본을 만들어줌


✅ 요약

복사 방식내부 리스트까지 분리됨?사용 상황
copy()❌ 참조 유지됨1단계 리스트
deepcopy()✅ 완전 복제중첩 리스트/객체

✅ 18. 리스트 슬라이싱 [:] (복사 vs 참조 혼동)


🔸 슬라이싱은 얕은 복사

a = [1, 2, 3]
b = a[:]

b[0] = 99
print(a)  # [1, 2, 3]
print(b)  # [99, 2, 3]

[:]는 새로운 리스트를 만들지만, 내부 값이 객체면 여전히 얕은 복사


🔥 실전 트랩 (2차원 리스트)

a = [[0] * 3] * 3
a[0][0] = 1
print(a)  
# [[1, 0, 0], [1, 0, 0], [1, 0, 0]] ← ❌ 모든 행이 연결됨

✅ 이건 3개의 리스트가 같은 리스트를 참조함

올바른 방법은:

a = [[0]*3 for _ in range(3)]

✅ 19. defaultdict, Counter (카운팅과 기본값)


🔸 defaultdict

from collections import defaultdict

d = defaultdict(int)
d['a'] += 1
print(d['a'])  # 1

➡ 기본값이 0으로 자동 설정됨
→ 실기에서 "키가 없으면 에러" 방지용


🔸 Counter

from collections import Counter

cnt = Counter(['a', 'b', 'a', 'c', 'a'])
print(cnt['a'])  # 3

➡ 요소별 등장 횟수를 자동으로 세어줌
→ 리스트/문자열에서 빈도 계산할 때 최고


✅ 20. reversed(), [::-1] (역순 처리)


🔸 reversed() 함수

a = [1, 2, 3]
for x in reversed(a):
    print(x)  # 3 2 1

메모리 낭비 없이 순회만 역순


🔸 [::-1] 슬라이싱

a = [1, 2, 3]
b = a[::-1]
print(b)  # [3, 2, 1]

➡ 새로운 리스트를 만들어 역순으로 리턴
→ 순회보다 값 자체가 필요한 경우 사용


✅ 차이 비교

방식복사 여부속도/메모리
reversed()❌ 복사 안 함메모리 효율적
[::-1]✅ 복사함리스트 새로 만듦

✅ 16~20 요약 정리표

번호주제핵심 요점실전 트랩
16sort() vs sorted()정렬은 sorted()가 리턴 있음b = a.sort()None
17copy() vs deepcopy()중첩 구조 복사는 deepcopy()copy()는 내부 참조 유지
18슬라이싱 [:]복사되지만 얕은 복사2차원 리스트 만들 때 터짐
19defaultdict, Counter기본값 및 카운팅 자동화dict['x'] += 1 에러 해결
20[::-1], reversed()역순 처리 방식reversed()는 복사 안 함

좋아, 이제 21번부터 25번까지 이어서 설명해줄게.
이 단계의 문법들은 실제 정보처리기사 실기에서 거의 반드시 등장하는 기본기이자,
파이썬을 능숙하게 쓰는 사람과 헷갈리는 초보자를 가르는 핵심 문법들이야.


✅ 21. 문자열 처리 함수 (strip, split, join)


🔹 strip(), rstrip(), lstrip()

s = "  hello \n"
print(s.strip())   # 'hello'
print(s.lstrip())  # 'hello \n'
print(s.rstrip())  # '  hello'
  • 공백(스페이스, 탭, 개행 등)을 제거
  • strip()은 양쪽, lstrip()은 왼쪽, rstrip()은 오른쪽만

🔹 split()

s = "a b c"
print(s.split())      # ['a', 'b', 'c']
print(s.split(" "))   # ['a', 'b', 'c']
  • 기본은 공백으로 나눔
  • 'a,b,c'.split(',')['a', 'b', 'c']

🔹 join()

lst = ['a', 'b', 'c']
print(' '.join(lst))     # 'a b c'
print(','.join(lst))     # 'a,b,c'
  • 리스트를 문자열로 합칠 때 사용

🔥 실전 트랩

input = "1,2,3"
numbers = input.split()
print(numbers)  # ❌ ['1,2,3']

→ split(',')로 써야 함


✅ 22. yield와 제너레이터


🔹 일반 함수와 차이

def normal():
    return [1, 2, 3]

def gen():
    yield 1
    yield 2
    yield 3

print(normal())   # [1, 2, 3]
print(list(gen()))  # [1, 2, 3]

🔹 제너레이터 특징

  • yield는 값을 하나씩 반환하고 함수의 상태를 유지
  • 반복 가능한 객체 (for 루프로 순회 가능)
  • 메모리를 적게 사용

🔥 실전 예시: 큰 수열 만들기

def count_up_to(n):
    for i in range(1, n + 1):
        yield i

for x in count_up_to(3):
    print(x)

출력:

1
2
3

✅ 제너레이터 vs 리스트 비교

항목리스트제너레이터 (yield)
메모리 사용크다작다
속도빠름느릴 수 있음
사용 시점미리 다 계산하나씩 계산

✅ 23. any() vs all() (조건 검사 축약)


🔹 any() – 하나라도 TrueTrue

a = [0, 0, 1]
print(any(a))  # True

🔹 all() – 모두 True여야 True

a = [1, 1, 1]
print(all(a))  # True

b = [1, 0, 1]
print(all(b))  # False

🔥 실전 예시

lst = ['abc', 'bcd', 'cde']
print(any(word.startswith('a') for word in lst))  # True
print(all(len(word) == 3 for word in lst))        # True

→ 리스트 조건 검사 시 매우 깔끔하게 사용 가능


✅ 24. with open() (파일 입출력의 정석)


🔹 기본 구조

with open('file.txt', 'r') as f:
    data = f.read()
    print(data)
  • 파일을 열고 f로 다룬다
  • 블록이 끝나면 자동으로 파일 닫힘

🔹 쓰기 모드

with open('file.txt', 'w') as f:
    f.write('Hello\n')

🔥 실전 트랩

f = open('file.txt', 'r')
data = f.read()
# 닫는 걸 까먹음 → 메모리/리소스 누수

✅ 항상 with를 쓰는 게 안전함


✅ 25. 클래스와 __init__ (초기화 함수)


🔹 기본 클래스 구조

class Person:
    def __init__(self, name):
        self.name = name

p = Person("Alice")
print(p.name)  # Alice
  • __init__은 생성자 (객체가 생성될 때 자동 실행)
  • self는 인스턴스 자신을 가리킴

🔥 실전 트랩

class A:
    def __init__(self, val=[]):  # ❌ 위험한 기본값
        self.val = val

→ 이건 모든 인스턴스가 같은 리스트 공유함
✅ 항상 None으로 초기화 후 내부에서 새 리스트 만들 것

def __init__(self, val=None):
    self.val = val if val is not None else []

✅ 21~25 요약표

번호주제핵심 포인트실전 용도
21문자열 함수strip, split, join입력 전처리
22yield제너레이터 함수메모리 아낌
23any, all조건검사 축약리스트 검사
24with open()파일 자동 닫힘입출력 안전하게
25__init__클래스 초기화객체 설계 핵심

0개의 댓글