본문 바로가기
Python

15. 컴프리헨션 - 파이썬다운 코드 작성법

by 샤나엘 2026. 2. 22.
반응형

컴프리헨션

15. 컴프리헨션 - 파이썬다운 코드 작성법

for문으로 리스트를 만드는 코드 3줄을 한 줄로 줄일 수 있다면? 파이썬만의 독특하고 강력한 문법인 컴프리헨션을 배워보자. 이것을 쓰느냐 안 쓰느냐가 파이썬 초보와 중급의 경계다.


리스트 컴프리헨션

기본 문법

# 기존 방식: for문으로 리스트 만들기
squares = []
for i in range(1, 6):
    squares.append(i ** 2)
print(squares)   # [1, 4, 9, 16, 25]

# 컴프리헨션: 한 줄로!
squares = [i ** 2 for i in range(1, 6)]
print(squares)   # [1, 4, 9, 16, 25]

 

컴프리헨션 구조

 

형식: [표현식 for 변수 in 반복대상]

# 문자열 처리
names = ["kim", "lee", "park"]
upper_names = [name.upper() for name in names]
print(upper_names)   # ['KIM', 'LEE', 'PARK']

# 길이 구하기
words = ["apple", "banana", "kiwi"]
lengths = [len(w) for w in words]
print(lengths)   # [5, 6, 4]

조건 필터링

# 기존 방식
evens = []
for i in range(1, 11):
    if i % 2 == 0:
        evens.append(i)
print(evens)   # [2, 4, 6, 8, 10]

# 컴프리헨션 + 조건
evens = [i for i in range(1, 11) if i % 2 == 0]
print(evens)   # [2, 4, 6, 8, 10]

형식: [표현식 for 변수 in 반복대상 if 조건]

# 양수만 필터링
numbers = [3, -1, 4, -5, 2, -8, 7]
positives = [n for n in numbers if n > 0]
print(positives)   # [3, 4, 2, 7]

# 문자열에서 모음만 추출
text = "Hello World"
vowels = [ch for ch in text if ch.lower() in "aeiou"]
print(vowels)   # ['e', 'o', 'o']

조건 표현식 (if-else)

# 짝수는 'E', 홀수는 'O'로 변환
labels = ["E" if n % 2 == 0 else "O" for n in range(1, 6)]
print(labels)   # ['O', 'E', 'O', 'E', 'O']

# 합격/불합격 판정
scores = [85, 42, 90, 67, 55]
results = ["합격" if s >= 60 else "불합격" for s in scores]
print(results)   # ['합격', '불합격', '합격', '합격', '불합격']

⚠️ 주의: 필터링 if는 뒤에, 변환 if-else는 앞에 온다!

  • 필터: [x for x in lst if 조건] — 조건에 맞는 것만 선택
  • 변환: [A if 조건 else B for x in lst] — 모든 요소를 변환

딕셔너리 컴프리헨션

# 이름과 점수로 딕셔너리 만들기
names = ["김철수", "이영희", "박민수"]
scores = [85, 92, 78]

grade_book = {name: score for name, score in zip(names, scores)}
print(grade_book)   # {'김철수': 85, '이영희': 92, '박민수': 78}

# 기존 딕셔너리 필터링
grade_book = {"김철수": 85, "이영희": 92, "박민수": 78, "최지원": 55}
passed = {name: score for name, score in grade_book.items() if score >= 60}
print(passed)   # {'김철수': 85, '이영희': 92, '박민수': 78}

# 키-값 뒤집기
original = {"a": 1, "b": 2, "c": 3}
flipped = {v: k for k, v in original.items()}
print(flipped)   # {1: 'a', 2: 'b', 3: 'c'}

형식: {키표현식: 값표현식 for 변수 in 반복대상}


세트 컴프리헨션

# 리스트에서 중복 제거하며 변환
numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {n ** 2 for n in numbers}
print(unique_squares)   # {1, 4, 9, 16}

# 문자열에서 고유 문자 (소문자 변환)
text = "Hello World"
chars = {ch.lower() for ch in text if ch.isalpha()}
print(chars)   # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

중첩 컴프리헨션

이중 for문도 컴프리헨션으로 작성할 수 있다.

# 기존 방식: 구구단 결과 리스트
results = []
for i in range(2, 4):
    for j in range(1, 4):
        results.append(i * j)
print(results)   # [2, 4, 6, 3, 6, 9]

# 컴프리헨션
results = [i * j for i in range(2, 4) for j in range(1, 4)]
print(results)   # [2, 4, 6, 3, 6, 9]

# 2차원 리스트 평탄화
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat)   # [1, 2, 3, 4, 5, 6, 7, 8, 9]

💡 팁: 중첩 컴프리헨션은 2단계까지만 사용하자. 3단계 이상은 일반 for문이 더 읽기 좋다.


언제 쓰고 언제 안 쓸까?

쓰면 좋을 때 안 쓰는 게 나을 때
간단한 변환/필터링 로직이 복잡할 때 (여러 줄의 처리)
새 리스트/딕셔너리 생성 부수 효과가 있을 때 (print, 파일 쓰기)
한 줄로 의도가 명확할 때 한 줄이 너무 길어질 때
# 좋은 예: 간결하고 의도가 명확
evens = [n for n in range(100) if n % 2 == 0]

# 나쁜 예: 너무 복잡해서 읽기 어려움
result = [f(x) if g(x) > 0 else h(x) for x in data if x is not None and len(x) > 3]
# → 이런 건 일반 for문으로 쓰는 게 낫다

실전 예시: 데이터 정제

# 원본 데이터 (불규칙한 형태)
raw_data = [" Kim ", "  lee", "PARK  ", "choi", "  JUNG "]

# 1. 공백 제거 + 소문자 통일
cleaned = [name.strip().lower() for name in raw_data]
print(cleaned)   # ['kim', 'lee', 'park', 'choi', 'jung']

# 2. 첫 글자만 대문자
formatted = [name.strip().title() for name in raw_data]
print(formatted)   # ['Kim', 'Lee', 'Park', 'Choi', 'Jung']

# 성적 데이터 처리
students = [
    {"이름": "김철수", "점수": 85},
    {"이름": "이영희", "점수": 92},
    {"이름": "박민수", "점수": 45},
    {"이름": "최지원", "점수": 78},
]

# 합격자 이름만 추출
passed_names = [s["이름"] for s in students if s["점수"] >= 60]
print(passed_names)   # ['김철수', '이영희', '최지원']

# 등급 부여
graded = {s["이름"]: "합격" if s["점수"] >= 60 else "불합격" for s in students}
print(graded)   # {'김철수': '합격', '이영희': '합격', '박민수': '불합격', '최지원': '합격'}

직접 해보기

문제 1. 1~20 중 3의 배수만 제곱하여 리스트로 만들어보자.

# 결과: [9, 36, 81, 144, 225, 324]

문제 2. 문장에서 단어 길이가 4 이상인 것만 대문자로 변환해보자.

sentence = "the quick brown fox jumps over the lazy dog"
# 결과: ['QUICK', 'BROWN', 'JUMPS', 'OVER', 'LAZY']

문제 3. 딕셔너리에서 값이 80 이상인 항목만 추출해보자.

scores = {"국어": 85, "수학": 72, "영어": 91, "과학": 68, "사회": 88}
# 결과: {'국어': 85, '영어': 91, '사회': 88}
정답 보기
# 문제 1
result = [i ** 2 for i in range(1, 21) if i % 3 == 0]
print(result)    # [9, 36, 81, 144, 225, 324]
‍
# 문제 2
sentence = "the quick brown fox jumps over the lazy dog"
result = [w.upper() for w in sentence.split() if len(w) >= 4]
print(result)    # ['QUICK', 'BROWN', 'JUMPS', 'OVER', 'LAZY']
‍
# 문제 3
scores = {"국어": 85, "수학": 72, "영어": 91, "과학": 68, "사회": 88}
high = {k: v for k, v in scores.items() if v >= 80}
print(high)    # {'국어': 85, '영어': 91, '사회': 88}

오늘의 정리

항목 내용
리스트 컴프리헨션 [표현식 for x in 대상]
필터링 [표현식 for x in 대상 if 조건]
변환 (if-else) [A if 조건 else B for x in 대상]
딕셔너리 {키: 값 for x in 대상}
원칙 한 줄로 읽기 좋을 때만 사용. 복잡하면 for문이 낫다

다음 편 예고: 자료구조 비교 총정리 - 상황별 선택 가이드

리스트, 튜플, 세트, 딕셔너리. 네 가지 자료구조를 모두 배웠는데, 실전에서 어떤 걸 써야 할까? 성능과 용도를 비교하며 최적의 선택을 내리는 법을 알아보자.


태그: 파이썬 Python 파이썬독학 리스트컴프리헨션 딕셔너리컴프리헨션 파이썬스러운코드 파이썬기초 IT교육

반응형

댓글