20260319 오늘의 학습: 문자열과 Set(집합)

Yesol Lee·2026년 3월 19일

COS Python

목록 보기
5/30

어제 학습 요약

  • 딕셔너리 활용: get(), Counter, lambda, 딕셔너리 정렬
  • 6문제 풀이, 1차 정답률 83%
  • 순회 중 삭제 패턴 list(dict) 학습

오늘 수업 계획

문자열 메서드 정리 → 문자열 문제 6문제 → 집합(set) 개념 + 연산 → 집합 문제 4문제 → 종합 복습 1문제


학습 내용 정리

1. 문자열 메서드 — Java String과 비교

메서드설명Java 비교
s.split(",")구분자로 쪼개서 리스트 반환s.split(",") (배열 반환)
",".join(lst)리스트를 구분자로 합치기String.join(",", arr)
s.replace("a","b")치환 (새 문자열 반환)동일
s.strip()양쪽 공백 제거s.trim()
s.find("x")찾으면 인덱스, 없으면 -1s.indexOf("x")
s.index("x")찾으면 인덱스, 없으면 에러!
s.count("a")특정 문자/문자열 등장 횟수— (직접 구현)
s.isdigit()전부 숫자인지s.matches("\\d+")
s.isalpha()전부 알파벳인지
s.upper() / s.lower()대/소문자 변환동일
s.startswith("x")접두사 확인동일
s.zfill(n)왼쪽 0 채우기

Java와 대부분 비슷하지만, count(), isdigit(), zfill() 같은 건 Python만의 편의 메서드다.

2. 문자열 핵심 포인트

문자열은 불변(immutable) — Java와 동일

s = "hello"
s[0] = "H"  # ❌ 에러! 문자열은 수정 불가
s = "H" + s[1:]  # ✅ 새 문자열 생성

split()의 함정 — COS Pro 빈출!

"a  b  c".split()    # ['a', 'b', 'c'] — 연속 공백 자동 처리
"a  b  c".split(" ") # ['a', '', 'b', '', 'c'] — 빈 문자열 포함!

인자 없이 split()을 호출하면 연속 공백을 하나로 처리하지만, split(" ")은 공백 하나하나를 구분자로 인식해서 빈 문자열이 생긴다. 이 차이가 시험에서 함정으로 나온다.

join()은 원소가 전부 문자열이어야 함

",".join([1, 2, 3])                    # ❌ 에러!
",".join(str(x) for x in [1, 2, 3])    # ✅ "1,2,3"

메서드 체이닝

text.lower().replace(" ", "")  # 소문자 변환 + 공백 제거를 한 줄에

문자열 메서드는 새 문자열을 반환하므로, 연속으로 이어붙일 수 있다.

3. 문자열 문제 풀이 — 주요 패턴

대소문자 무시 비교: 양쪽 다 lower()

def count_word(sentence, word):
    converted = sentence.lower()
    target = word.lower()
    # 이후 비교

숫자만 추출: isdigit()

digits = ""
for ch in phone:
    if ch.isdigit():
        digits += ch

회문 판별: 전처리 후 슬라이싱 뒤집기

def is_palindrome(text):
    cleaned = text.lower().replace(" ", "")
    return cleaned == cleaned[::-1]

4. 집합(set) 기초

특징설명
중복 없음{1, 1, 2}{1, 2}
순서 없음인덱싱 불가 (s[0] ❌)
변경 가능추가/삭제 가능
s = {1, 2, 3}
s = set([1, 2, 2, 3])    # 리스트에서 변환 → {1, 2, 3}
empty = set()             # ⚠️ {}는 빈 딕셔너리!

{}로 빈 집합을 만들 수 없다는 점이 자주 혼동되는 포인트다.

추가/삭제

s.add(4)        # 하나 추가
s.remove(4)     # 삭제 (없으면 KeyError!)
s.discard(4)    # 삭제 (없어도 에러 안 남)

5. 집합 연산 — COS Pro 빈출!

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

a | b     # 합집합:    {1, 2, 3, 4, 5, 6}
a & b     # 교집합:    {3, 4}
a - b     # 차집합:    {1, 2}
a ^ b     # 대칭차집합: {1, 2, 5, 6}

수업 중 질문: "메서드 버전은 각각 뭐야?"

→ 연산자와 메서드는 결과가 동일하다.

연산연산자메서드
합집합a \| ba.union(b)
교집합a & ba.intersection(b)
차집합a - ba.difference(b)
대칭차집합a ^ ba.symmetric_difference(b)

COS Pro에서는 연산자 버전이 더 자주 출제된다. 메서드 이름은 영어 뜻 그대로라 외우기 쉽다.

6. 문제 풀이 — 두 리스트의 공통 원소 추출 (빈칸 채우기)

두 리스트에서 공통 원소만 추출하여 정렬된 리스트로 반환하는 문제.

def common_elements(list1, list2):
    set1 = set(list1)
    set2 = set(list2)
    common = set1 & set2        # 교집합
    return sorted(common)       # 정렬된 리스트로 반환

자주 쓰는 패턴: 중복 제거 후 정렬

nums = [3, 1, 2, 1, 3]
result = sorted(set(nums))    # [1, 2, 3]

7. 문제 풀이 — 순서 유지 중복 제거 (빈칸 채우기)

문자열 리스트에서 중복을 제거하되, 원래 등장 순서를 유지하여 반환하는 문제. 단순 set()은 순서를 보장하지 않으므로 별도 패턴이 필요하다.

def unique_ordered(items):
    seen = set()       # ⚠️ 빈 set으로 시작!
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

여기서 seenset(items)로 시작하면 이미 모든 항목이 "본 것"으로 처리되어 아무것도 추가되지 않는다. set()으로 시작해야 하나씩 추적할 수 있다.

또한 item not in result(리스트 검색)보다 item not in seen(set 검색)이 훨씬 빠르다. 리스트는 O(n), set은 O(1)이므로 "이미 봤는지 확인"은 set을 쓰는 게 정석이다.

8. 문제 풀이 — 모든 학생의 공통 수강 과목 (함수 작성)

학생들의 수강 과목이 딕셔너리로 주어질 때, 모든 학생이 공통으로 수강하는 과목을 정렬하여 반환하는 문제. 여러 집합의 교집합을 누적하는 패턴이 핵심이다.

def common_courses(students):
    courses_list = list(students.values())
    result = set(courses_list[0])       # 첫 번째 값으로 초기화
    for courses in courses_list[1:]:    # 나머지 순회
        result = result & set(courses)  # 교집합 누적
    return sorted(result)

이 패턴의 핵심:
1. dict.values()list()로 변환하면 인덱스 접근 가능
2. 첫 번째 값으로 초기화 → 나머지 순회하며 누적 연산
3. 학생 수가 몇 명이든 동작하는 일반화된 코드

처음에는 list1, list2, list3 = students.values()로 3명 고정 언패킹을 했지만, 이러면 학생 수가 바뀔 때 깨진다. 하드코딩 대신 for문으로 일반화하는 습관이 중요하다.

9. 종합 문제 — 첫 글자별 그룹핑 (함수 작성)

단어 리스트를 받아서, 각 단어의 첫 글자를 키로 하고 해당 글자로 시작하는 단어들의 리스트를 값으로 하는 딕셔너리를 반환하는 문제. 단어는 소문자 통일, 중복 제거, 알파벳 순 정렬이 필요하다. 문자열 + 딕셔너리 + 집합을 조합한 종합 문제:

def group_by_initial(words):
    list1 = sorted(set([word.lower() for word in words]))  # 전처리
    result = {}
    for word in list1:
        if word[0] in result:
            result[word[0]].append(word)
        else:
            result[word[0]] = [word]
    return result

전처리(lower + set + sorted)를 먼저 완료한 뒤 딕셔너리를 구성하는 접근이 깔끔하다. sorted를 먼저 했기 때문에 각 그룹 안의 단어들도 자동으로 정렬된 상태가 된다.


오늘의 결과

  • 총 11문제 풀이, 1차 정답률 73% (빈칸/디버깅 100%, 함수 작성은 힌트 후 해결)
  • 문자열 처리 + 집합 연산 + 종합 문제까지 Phase 1 핵심 자료구조 거의 완료
  • 다음 학습: Python 내장함수 정리 + 튜플, Phase 1 마무리 방향
profile
문서화를 좋아하는 개발자

0개의 댓글