Python by Structure: 리스트 컴프리헨션과 숨겨진 복잡성
Source: Dev.to
Introduction
Timothy는 데이터 처리 코드를 리팩터링하던 중 이해할 수 없는 리스트 컴프리헨션을 마주했습니다.
“Margaret, 누군가 이 컴프리헨션을 작성했는데 무슨 뜻인지 모르겠어요. 한 줄에 다 적혀 있어서 머리가… 멈추네요.”
Margaret는 코드를 보았습니다:
result = [item for sublist in data for item in sublist if item > 0 if item % 2 == 0]
“아,” Margaret가 말했습니다. “이건 똑똑함을 넘어 혼란을 주는 컴프리헨션이군요. 실제로 무슨 일이 일어나는지 보여줄게요.”
The Problem: Comprehensions Gone Wrong
“컴프리헨션은 강력합니다,” Margaret가 설명했습니다, “하지만 너무 복잡하게 쓰면 읽기 전용 코드가 될 수 있어요. 루프를 중첩하고 필터를 쌓을 때 실행 순서는 대부분의 사람들이 기대하는 것과 다를 수 있거든요.”
Timothy는 고개를 끄덕였습니다. “컴프리헨션은 코드를 더 읽기 쉽게 만든다고 들었는데, 이건 정반대네요.”
Basic Comprehension
numbers = [1, 2, 3, 4, 5]
squares = [n * n for n in numbers]
English View
Set numbers to [1, 2, 3, 4, 5].
Set squares to:
List comprehension: n * n
For each n in numbers
“이건 명확하죠,” Margaret가 말했습니다. “각 숫자를 제곱해서 새로운 리스트를 만들고 있는 거예요.”
Adding Filters
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = [n * n for n in numbers if n % 2 == 0]
English View
Set numbers to [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
Set even_squares to:
List comprehension: n * n
For each n in numbers
If n % 2 == 0
Result:
[4, 16, 36, 64, 100]
Multiple Filters
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [n for n in numbers if n > 3 if n % 2 == 0]
English View
Set numbers to [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
Set result to:
List comprehension: n
For each n in numbers
If n > 3
If n % 2 == 0
“두 개의
if문이 연속으로 있으면 OR인가요, AND인가요?”
두 if 절은 AND 로 결합됩니다. 즉 if n > 3 and n % 2 == 0 와 동일합니다.
Result:
[4, 6, 8, 10]
Nested Loops
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for row in matrix for item in row]
English View
Set matrix to [[1, 2, 3], [4, 5, 6], [7, 8, 9]].
Set flat to:
List comprehension: item
For each row in matrix
For each item in row
Equivalent loop:
flat = []
for row in matrix:
for item in row:
flat.append(item)
Result:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Combining Nested Loops and Filters
data = [[1, -2, 3], [4, -5, 6], [7, 8, -9]]
result = [item for sublist in data for item in sublist if item > 0 if item % 2 == 0]
English View
Set data to [[1, -2, 3], [4, -5, 6], [7, 8, -9]].
Set result to:
List comprehension: item
For each sublist in data
For each item in sublist
If item > 0
If item % 2 == 0
Expanded version:
result = []
for sublist in data: # First For
for item in sublist: # Second For
if item > 0: # First If
if item % 2 == 0: # Second If
result.append(item)
Result:
[4, 6, 8]
When Comprehensions Become Too Complex
Guidelines
Use comprehensions when:
- The logic fits comfortably on one line
- The transformation is simple and obvious
- You have at most one level of nesting
- Filters are straightforward
Avoid comprehensions when:
- You need nested loops with complex conditions
- The logic requires multiple steps
- Reading it aloud doesn’t make immediate sense
- You’re tempted to add comments explaining it
A more readable rewrite of the complex example:
# More readable version
result = []
for sublist in data:
for item in sublist:
if item > 0 and item % 2 == 0:
result.append(item)