본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

컴프리헨션과 제너레이터 — 결과의 모양을 바로 쓰기

~18 min · comprehension, generator, idiom, pythonic

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

리스트·딕셔너리·집합 컴프리헨션은 단순한 변환과 필터를 결과 모양 그대로 선언해. append를 위한 반복문이나 짧은 람다를 붙인 map·filter보다 읽기 쉬운 경우가 많아. 반대로 str.upper처럼 이미 이름이 뜻을 말해 주는 함수를 그대로 적용한다면 map도 자연스러워.

결과를 한 번만 소비하거나 sum·any·all·max 같은 축약 함수에 바로 넘길 때는 대괄호 대신 제너레이터 표현식을 써 중간 리스트를 만들지 않아. 큰 입력이나 무한 시퀀스에서는 메모리와 단락 평가의 이점이 커.

하지만 기록, 여러 단계 변경, 여러 갈래 예외 복구가 들어가면 한 줄이 상태를 숨겨. Python다운 코드는 줄 수를 줄이는 경쟁이 아니라 독자가 한 번에 추적할 상태를 줄이고 문제 복잡도에 문법을 맞추는 일이야.

Code

반복문과 리스트 컴프리헨션 비교·python
# Loop
result = []
for n in range(10):
    if n % 2 == 0:
        result.append(n * n)

# 컴프리헨션 — 이 모양엔 선호
result = [n * n for n in range(10) if n % 2 == 0]
print(result)            # [0, 4, 16, 36, 64]
map·filter를 컴프리헨션으로 읽기·python
nums = [1, 2, 3, 4, 5]

# functional — wordy
result = list(map(lambda x: x * 2, filter(lambda x: x > 2, nums)))
print(result)            # [6, 8, 10]

# 컴프리헨션 — 직접
result = [x * 2 for x in nums if x > 2]
print(result)            # [6, 8, 10]

# 근데 named 함수 가진 map — 경쟁력
words = ["alpha", "beta"]
upper_a = list(map(str.upper, words))
upper_b = [w.upper() for w in words]
# 둘 다 OK. 컴프리헨션 약간 선호.
축약 함수에 제너레이터 바로 넘기기·python
# 컴프리헨션 — list 먼저 빌드
total = sum([x * x for x in range(1_000_000)])

# Generator expression — list를 만들지 않음, 값 stream
total = sum(x * x for x in range(1_000_000))
# 같은 답, 메모리 훨씬 적음

# any/all/max/min/set 도 같은 idiom
any(x < 0 for x in nums)
max(x * 2 for x in nums)
set(x % 7 for x in range(100))
명시적 반복문이 더 나은 경우·python
# 원소별 로직이 다단계일 때
result = []
for user in users:
    addr = lookup_address(user.id)
    if addr.country == "KR":
        if user.is_active:
            result.append({
                "name": user.name,
                "email": user.email,
                "address": addr.format(),
            })
# 이거 컴프리헨션에 쑤셔넣으면 안 읽힘.
# 명시적 loop 가 여기 더 pythonic.

External links

Exercise

append로 문자열을 모으는 반복문은 리스트 컴프리헨션으로, 0~99 짝수 제곱의 합은 제너레이터로, 이름과 길이는 딕셔너리 컴프리헨션으로, 단어의 첫 글자는 집합 컴프리헨션으로 바꿔. 사용자 딕셔너리를 다섯 단계로 처리하는 반복문은 왜 그대로가 나은지도 설명해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.