파이썬은 기존 리스트에서 새로운 리스트를 만들어내는 간결하고 우아한 문법을 제공합니다. 이를 리스트 컴프리헨션(List Comprehension)이라고 부르며, 파이썬이 지원하는 대표적인 함수형 프로그래밍 개념 중 하나입니다.
리스트 컴프리헨션은 리스트의 각 요소에 함수를 적용하거나 특정 조건으로 필터링할 때 매우 유용합니다. 다만 잘못 사용하면 오히려 가독성을 해칠 수 있으므로, 올바른 사용법을 익히는 것이 중요합니다.
기본 문법
리스트 컴프리헨션의 일반적인 문법은 다음과 같습니다.
[expr for element in iterable if condition]
위 코드는 아래의 for문과 동일하게 동작합니다.
for element in iterable: if condition: expr
예를 들어, 리스트에 있는 각 숫자의 제곱값을 구하고 싶다면 계산식과 반복할 입력 시퀀스만 지정하면 됩니다.
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> squares = [x**2 for x in lst] >>> print(squares) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
리스트 컴프리헨션 vs for문
먼저 전통적인 for문을 사용해 0~9 사이의 짝수를 구하는 코드를 살펴보겠습니다.
# FOR문 사용 evens = [] for i in range(10): if i % 2 == 0: evens.append(i) print(evens)
실행 결과
[0, 2, 4, 6, 8]
위 코드를 리스트 컴프리헨션으로 작성하면 훨씬 간결하고 빠릅니다.
>>> [i for i in range(10) if i % 2 == 0] [0, 2, 4, 6, 8]
보시는 것처럼 리스트 컴프리헨션을 사용하면 코드가 훨씬 짧아지고, 불필요한 요소 없이 로직이 한 줄로 깔끔하게 정리됩니다.
리스트 컴프리헨션 vs 람다 함수(map)
인자가 하나인 단순한 연산이라면, 리스트 컴프리헨션이 내장 함수 map보다 명확합니다. map은 연산을 위해 람다(lambda) 함수를 별도로 생성해야 하므로 코드가 시각적으로 번잡스러워집니다.
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> list(map(lambda x: x**2, lst)) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
게다가 map과 달리 리스트 컴프리헨션은 입력 리스트에서 원하는 항목만 쉽게 필터링할 수 있어, 결과에서 불필요한 값들을 손쉽게 제외할 수 있습니다.
조건식을 활용한 리스트 컴프리헨션
조건을 여러 개 추가하는 것도 가능합니다. 예를 들어 100 미만의 숫자 중 2와 5로 모두 나누어떨어지는 수만 구하고 싶다면 다음과 같이 작성합니다.
>>> lst = [x for x in range(100) if x % 2 == 0 if x % 5 == 0] >>> print(lst) [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
또 다른 예로, 2로 나누어떨어지는 숫자(짝수)만 골라 제곱값을 구해보겠습니다. 반복문 뒤에 조건식을 추가하면 됩니다.
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> even_squares = [x**2 for x in lst if x % 2 == 0] >>> print(even_squares) [4, 16, 36, 64, 100]
1부터 100 사이의 모든 짝수를 구하는 코드도 다음처럼 간단하게 작성할 수 있습니다.
>>> # 1~100 사이의 짝수 리스트 evens = [i for i in range(1, 100) if not i % 2] >>> print(evens) [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
마무리: 성능까지 챙기자
리스트 컴프리헨션은 방대한 양의 데이터를 반복 처리할 때 일반적인 for문보다 훨씬 빠르게 실행됩니다. 가독성만으로 충분히 사용할 이유가 되지만, 여기에 실행 속도까지 더해지니 적극적으로 활용할 가치가 충분합니다.