파이썬 리스트 컴프리헨션 — 한 줄로 리스트 만들기 (사용법·예제)
파이썬 리스트 컴프리헨션이란?
파이썬 리스트 컴프리헨션(list comprehension)은 기존의 for 반복문을 한 줄로 압축해 새 리스트를 만드는 문법입니다. 코드가 짧아질 뿐 아니라 일반 for문보다 대체로 약간 더 빠릅니다. 입문 개발자가 가장 먼저 익혀두면 좋은 파이썬 표현식 중 하나입니다.
기본 문법
리스트 컴프리헨션의 기본 형태는 다음과 같습니다.
[표현식 for 변수 in 반복가능객체]
예를 들어 0부터 4까지 제곱한 값을 담는 리스트를 만들어 보겠습니다. 먼저 일반 for문 방식입니다.
squares = []
for n in range(5):
squares.append(n ** 2)
print(squares) # [0, 1, 4, 9, 16]
같은 결과를 리스트 컴프리헨션으로 한 줄에 작성할 수 있습니다.
squares = [n ** 2 for n in range(5)]
print(squares) # [0, 1, 4, 9, 16]
조건문(if) 추가하기
특정 조건을 만족하는 값만 걸러내려면 뒤에 if를 붙입니다.
evens = [n for n in range(10) if n % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
if-else(삼항 표현식) 사용하기
걸러내는 것이 아니라 값을 변환할 때는 if-else를 for 앞쪽 표현식 자리에 씁니다. 위치가 다르다는 점에 주의하세요.
labels = ["짝수" if n % 2 == 0 else "홀수" for n in range(5)]
print(labels) # ['짝수', '홀수', '짝수', '홀수', '짝수']
중첩 리스트 컴프리헨션
2중 for문도 표현할 수 있습니다. 작성 순서는 바깥 for가 먼저, 안쪽 for가 나중입니다.
pairs = [(x, y) for x in range(2) for y in range(2)]
print(pairs) # [(0, 0), (0, 1), (1, 0), (1, 1)]
2차원 리스트를 평탄화(flatten)할 때도 유용합니다.
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in matrix for num in row]
print(flat) # [1, 2, 3, 4, 5, 6]
실전 예제
문자열 리스트에서 길이가 3 이상인 단어만 대문자로 바꿔 모으는 예제입니다.
words = ["hi", "python", "go", "code"]
result = [w.upper() for w in words if len(w) >= 3]
print(result) # ['PYTHON', 'CODE']
딕셔너리나 집합도 비슷한 문법으로 만들 수 있습니다(컴프리헨션 패턴 확장).
square_map = {n: n ** 2 for n in range(4)}
print(square_map) # {0: 0, 1: 1, 2: 4, 3: 9}
unique_lengths = {len(w) for w in words}
print(unique_lengths) # {2, 4, 6}
자주 하는 실수
- if-else 위치 혼동: 값을 변환하는
if-else는 for 앞, 걸러내는if는 for 뒤입니다. - 지나친 압축: 3중 이상 중첩이나 복잡한 조건이 들어가면 가독성이 떨어집니다. 이럴 땐 그냥 일반 for문이 낫습니다.
- 대용량 데이터에 리스트 사용: 메모리에 전부 올리므로, 한 번만 순회한다면 대괄호 대신 소괄호를 쓰는 제너레이터 표현식
(n for n in range(10**8))이 메모리에 유리합니다. - 부수 효과 남용:
print()처럼 값을 반환하지 않는 함수를 컴프리헨션 안에서 호출하면None이 채워진 리스트가 생깁니다.
리스트 컴프리헨션 vs 일반 for문 비교
| 구분 | 리스트 컴프리헨션 | 일반 for문 |
|---|---|---|
| 코드 길이 | 한 줄 | 여러 줄 |
| 속도 | 대체로 약간 빠름 | 상대적으로 느림 |
| 가독성 | 단순할 때 우수 | 복잡한 로직에 유리 |
| 적합한 경우 | 변환·필터링 | 여러 동작·예외 처리 |
자주 묻는 질문
Q. 리스트 컴프리헨션이 항상 for문보다 빠른가요?
대부분의 단순 변환·필터링에서는 함수 호출 오버헤드가 줄어 약간 더 빠릅니다. 다만 차이가 크지 않으므로 속도보다는 가독성을 기준으로 선택하는 것이 좋습니다.
Q. 컴프리헨션 안에서 변수를 만들어 재사용할 수 있나요?
파이썬 3.8부터는 바다코끼리 연산자 :=로 가능합니다. 예: [y for x in data if (y := f(x)) > 0]. 다만 남용하면 읽기 어려워지니 주의하세요.
Q. 결과가 너무 커서 메모리가 부담될 때는요?
대괄호 대신 소괄호를 쓰는 제너레이터 표현식을 사용하세요. sum(n*n for n in range(1000000))처럼 즉시 소비하는 경우 리스트를 만들지 않아 메모리를 절약합니다.