20260326 오늘의 학습: Phase 1 종합 복습 테스트

Yesol Lee·2026년 3월 26일

COS Python

목록 보기
9/23

어제 학습 요약

  • 예외 처리(try/except/else/finally) 학습, Java의 try/catch와 비교
  • 10문제 풀이, 1차 정답률 70%
  • Phase 1 마지막 주제까지 완료

오늘 수업 계획

Phase 1 전 영역 종합 복습 테스트. 리스트, 딕셔너리, 문자열, 집합, 내장함수, 튜플, 함수, 예외 처리까지 골고루 10문제를 풀어 Phase 2 전환 여부를 판단한다.


학습 내용 정리

문제 1 (빈칸) — 2차원 배열 대각선 합

n×n 행렬의 주대각선 합을 구하는 문제. 대각선 원소는 행과 열 인덱스가 같으므로 matrix[i][i]로 접근한다.

total += matrix[i][i]  # (0,0), (1,1), (2,2) → 주대각선

✅ 1차 정답

문제 2 (빈칸) — 딕셔너리 최빈 문자

문자열에서 가장 많이 등장한 문자를 반환하는 문제.

1차 시도: sorted(count)[0] → 오답. sorted(dict)는 키를 알파벳순으로 정렬할 뿐, 등장 횟수와 무관하다.

정답: max(count, key=count.get)

max(count, key=count.get)   # 값(등장 횟수)이 가장 큰 키를 반환
min(count, key=count.get)   # 값이 가장 작은 키를 반환

수업 중 질문: "key=count.get할 때 get()에 키 값이 없어도 되나?"
count.get은 호출(count.get('a'))이 아니라 함수 자체를 넘기는 것. max가 내부적으로 각 키를 넣어서 호출해주기 때문에 우리가 키를 지정할 필요가 없다. Java의 메서드 레퍼런스(count::get)와 같은 개념.

문제 3 (빈칸) — 문자열 capitalize + join

각 단어의 첫 글자를 대문자로 바꾸는 문제. capitalize() 메서드를 써봤더니 동작했다.

result.append(w.capitalize())   # 첫 글자 대문자 + 나머지 소문자
return " ".join(result)
방법동작
w.capitalize()첫 글자 대문자 + 나머지 소문자
w[0].upper() + w[1:]첫 글자만 대문자 + 나머지 그대로
w.title()각 단어 첫 글자 대문자 (문자열 전체에 적용)

capitalize()를 몰라도 w[0].upper() + w[1:]로 대체 가능.

✅ 1차 정답

문제 4 (빈칸) — set 교집합 + 순서 유지

두 리스트의 공통 원소를 원래 순서 유지하며 반환하는 문제.

1차 시도: 리스트 컴프리헨션으로 교집합 리스트를 만들어 비교 → 동작은 하지만 set을 활용하는 문제 의도와 다름.

정답: list2를 set으로 변환 후 in 검사.

common = set(list2)
return [x for x in list1 if x in common]

set을 쓰면 in 검색이 O(1)으로 빠르다.

문제 5 (빈칸) — 다중 정렬 키

점수 내림차순 + 이름 오름차순으로 정렬하는 문제. 정렬 기준이 여러 개일 때 튜플로 묶어서 반환한다는 걸 새로 배웠다.

sorted(students, key=lambda x: (-x[1], x[0]))

-를 붙이면 크기 관계가 뒤집혀서 내림차순이 된다. 단, 숫자에만 가능.

수업 중 질문: "조건 2개 이상이라 튜플로 줘야 될 때 reverse=True는 어디에?"
reverse=Truesorted()의 매개변수로 넣지만 전체 기준이 다 뒤집히므로, 방향이 섞여 있으면 사용 불가.

상황방법
기준이 같은 방향key=(기준1, 기준2) + reverse=True/False
숫자가 다른 방향- 트릭: (-x[1], x[0])
문자열이 다른 방향sorted 두 번 (덜 중요한 기준 먼저)

sorted 두 번 쓰는 방법은 Python의 안정 정렬(stable sort) 을 이용. 같은 값이면 이전 순서를 유지하므로, 덜 중요한 기준을 먼저 정렬하고 더 중요한 기준을 나중에 정렬하면 된다.

문제 6 (디버깅) — nonlocal 클로저

바깥 함수의 변수를 내부 함수에서 수정하려면 nonlocal 선언이 필요하다.

def increment(n):
    nonlocal count      # 함수 시작 부분에 선언 (관례)
    for i in range(n):
        count += 1

✅ 1차 정답

문제 7 (디버깅) — except에서 continue

변환 실패한 값을 "건너뛰는" 함수인데, except에서 실패한 값을 리스트에 추가하고 있었다. result.append(s)continue로 수정.

수업 중 질문: "int(4.5)는 4가 되는데 int('4.5')는 ValueError가 뜨는 이유?"
int()는 입력 타입에 따라 동작이 다르다. float → 소수점 버림, 문자열 → 정수 형태만 파싱 가능. "4.5"를 정수로 바꾸려면 int(float("4.5"))로 두 단계 거쳐야 한다.

✅ 1차 정답

문제 8 (함수 작성) — 투표 집계

def get_winner(votes):
    result = {}
    for vote in votes:
        result[vote] = result.get(vote, 0) + 1
    return max(result, key=result.get)

문제 2에서 배운 max(dict, key=dict.get) 패턴을 바로 활용했다. 개선점으로 if/else 분기 없이 get(vote, 0)만으로 충분하고, sorted()[0] 대신 max()가 더 효율적이라는 피드백을 받았다. sorted()는 전체를 정렬(O(n log n))하지만 max()는 한 번 순회(O(n))만 하면 되기 때문.

✅ 1차 정답

문제 9 (함수 작성) — 애너그램 판별

사고 과정: palindrome과 헷갈림 → set 교집합은 중복 제거돼서 안됨 → 값을 빼가면서 체크? → 힌트 후 sorted 비교로 해결.

def is_anagram(s1, s2):
    return sorted(s1) == sorted(s2)

정렬하면 글자 구성이 같은지 바로 비교 가능. Counter(s1) == Counter(s2)도 유효.

수업 중 질문: "Counter가 뭔지 찾아봤는데 딕셔너리끼리도 == 비교가 가능한가?"
→ 가능. 키와 값이 모두 같으면 True, 순서와 무관. Java의 map1.equals(map2)와 동일.

문제 10 (함수 작성) — 달팽이 수열 (Spiral Matrix)

가장 난이도가 높았던 문제. 힌트를 받아 방향 배열 + 방향 전환 구조로 직접 구현했다.

def make_spiral(n):
    grid = [[0] * n for _ in range(n)]
    dr = [0, 1, 0, -1]       # 오른쪽 → 아래 → 왼쪽 → 위
    dc = [1, 0, -1, 0]
    r, c = 0, 0
    d = 0

    for num in range(1, n * n + 1):
        grid[r][c] = num
        nr, nc = r + dr[d], c + dc[d]

        if nr < 0 or nr >= n or nc < 0 or nc >= n or grid[nr][nc] != 0:
            d = (d + 1) % 4
            nr, nc = r + dr[d], c + dc[d]

        r, c = nr, nc
    return grid

디버깅 과정: n=3은 통과했는데 n=4에서 실패. 원인은 if d == n으로 방향 리셋을 했기 때문. n=3일 때 d == 3이 우연히 맞았지만, n=4일 때 d == 4는 절대 발생하지 않음. (d + 1) % 4로 수정하여 해결.

자발적 추가 연습: 반시계 방향 + 역순(n×n → 1)도 직접 구현. 방향 배열만 바꾸고 range를 역순으로 변경하여 성공.


오늘의 결과

  • Phase 1 종합 테스트 10문제 완료, 1차 정답률 60% (6/10), 최종 전부 정답
  • 1차 정답률 80% 미달이므로 Phase 2 전환 전 약점 보충 필요 (dict+key 패턴, 다중 정렬, 알고리즘 구현)
  • 다음 학습: 약점 영역 보충 연습 후 Phase 2 전환 예정
profile
문서화를 좋아하는 개발자

0개의 댓글