[Python] 파이썬 컴프리헨션(Comprehension)

·2025년 6월 30일

Python

목록 보기
30/33

💡 컴프리헨션이란?

파이썬에서 리스트, 딕셔너리, 셋 등자료구조를 간결하게 생성할 수 있는 문법
반복문과 조건문을 한 줄로 표현할 수 있어 코드를 더 간결하고 읽기 쉽게 만들어줌


✔️ 1. 리스트 컴프리헨션 (List Comprehension)

기본 문법

[표현식 for 항목 in 순서열 if 조건]

예제1. 숫자 필터링

아래의 리스트에서 숫자 5보다 큰 숫자만 선택해서 리스트를 구성하세요.

컴프리헨션을 사용하지 않았을 때:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = []
for i in numbers:
    if i > 5:
        result.append(i)
print(result)	# [6, 7, 8, 9, 10]

컴프리헨션을 사용했을 때:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [i for i in numbers if i > 5]

print(result)   #[6, 7, 8, 9, 10]

문제1. 짝수 필터링

1부터 20까지의 숫자 중 짝수만 선택해서 리스트를 구성하시오.

컴프리헨션을 사용하지 않았을 때:

numbers = range(1, 21)

result = []
for num in numbers:
    if num % 2 == 0:
        result.append(num)
print(result)

# 출력: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

컴프리헨션을 사용했을 때:

numbers = range(1, 21)
result = [num for num in numbers if num % 2 == 0]
print(result)   # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

예제2. 짝수 제곱 리스트 만들기

컴프리헨션을 사용하지 않았을 때:

numbers = range(1, 11)

result = []
for num in numbers:
    if num % 2 == 0:
        result.append(num ** 2)
print(result)	# [4, 16, 36, 64, 100]

컴프리헨션을 사용했을 때:

numbers = range(1, 11)
result = [num**2 for num in numbers if num % 2 == 0]
print(result)   # [4, 16, 36, 64, 100]

문제2. 3의 배수 세제곱

1부터 20까지의 숫자 중 3의 배수만 골라 세제곱한 리스트를 만드시오.

컴프리헨션을 사용하지 않았을 때:

numbers = range(1, 21)

result = []
for num in numbers:
    if num % 3 == 0:
        result.append(num ** 3)
print(result)	# [27, 216, 729, 1728, 3375, 5832]

컴프리헨션을 사용했을 때:

numbers = range(1, 21)

result = [num**3 for num in numbers if num % 3 == 0]
print(result)   # [27, 216, 729, 1728, 3375, 5832]

✔️ 2. 딕셔너리 컴프리헨션 (Dictionary Comprehension)

기본 문법

{키_표현식: 값_표현식 for 항목 in 순서열 if 조건}

예제1. 문자열 길이 딕셔너리

문자열을 키로, 문자열의 길이를 값으로 하는 딕셔너리를 만드세요.

컴프리헨션을 사용하지 않았을 때:

words = ["apple", "banana", "cherry", "date", "elderberry"]

result = {}
for word in words:
    result[word] = len(word)
print(result)

# 출력: {'apple': 5, 'banana': 6, 'cherry': 6, 'date': 4, 'elderberry': 10}

컴프리헨션을 사용했을 때:

words = ["apple", "banana", "cherry", "date", "elderberry"]

result = { i: len(i) for i in words }
print(result)

# 출력: {'apple': 5, 'banana': 6, 'cherry': 6, 'date': 4, 'elderberry': 10}

문제1. 제곱 딕셔너리

1부터 10까지의 숫자를 키로, 그 숫자의 제곱을 값으로 하는 딕셔너리를 만드시오.

컴프리헨션을 사용하지 않았을 때:

result = {}
for num in range(1, 11):
    result[num] = num ** 2
print(result)

# 출력: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}

컴프리헨션을 사용했을 때:

result = {num: num**2 for num in range(1, 11)}
print(result)

# 출력: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}

예제2. 딕셔너리 필터링

아래의 딕셔너리에서 값이 10 이상인 키와 쌍을 필터링하여 새로운 딕셔너리로 구성하세요.

컴프리헨션을 사용하지 않았을 때:

a = {'사과': 8, '바나나': 15, '체리': 5, '배': 12, '망고': 20}

result = {}
for key, value in a.items():
    if value >= 10:
        result[key] = value
print(result)	# {'바나나': 15, '배': 12, '망고': 20}

# 위와 같음
a = {'사과': 8, '바나나': 15, '체리': 5, '배': 12, '망고': 20}
result = {}
for i in a.items():
    if i[1] >= 10:
        result[i[0]] = i[1]
print(result)

컴프리헨션을 사용했을 때:

a = {'사과': 8, '바나나': 15, '체리': 5, '배': 12, '망고': 20}

result = {key: value for key, value in a.items() if value >= 10}
print(result)   # {'바나나': 15, '배': 12, '망고': 20}

문제2. 짝수 값 필터링

다음 딕셔너리에서 값이 짝수인 키-값 쌍만 선택하여 새로운 딕셔너리를 만드시오.

컴프리헨션을 사용하지 않았을 때:

numbers = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8}

result = {}
for key, value in numbers.items():
    if value % 2 == 0:
        result[key] = value
print(result)	# {'b': 2, 'd': 4, 'f': 6, 'h': 8}

컴프리헨션을 사용했을 때:

numbers = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8}

result = {key: value for key, value in numbers.items() if value % 2 == 0}
print(result)	# {'b': 2, 'd': 4, 'f': 6, 'h': 8}

문제3. 첫 글자 딕셔너리

다음 문자열 리스트에서 각 문자열의 첫 글자를 키로, 해당 문자열을 값으로 하는 딕셔너리를 만드시오.

컴프리헨션을 사용하지 않았을 때:

fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']

result = {}
for fruit in fruits:
    result[fruit[0]] = fruit
print(result)

# 출력: {'a': 'apple', 'b': 'banana', 'c': 'cherry', 'd': 'date', 'e': 'elderberry'}

컴프리헨션을 사용했을 때:

fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']

result = {fruit[0]: fruit for fruit in fruits}
print(result)

# 출력: {'a': 'apple', 'b': 'banana', 'c': 'cherry', 'd': 'date', 'e': 'elderberry'}

✔️ 3. 셋 컴프리헨션 (Set Comprehension)

중복을 제거해줌
중괄호 { }가 set임

💡 추가할 때
list에서는 --> append
set에서는 --> add

기본 문법

{표현식 for 항목 in 순서열 if 조건}

예제1. 짝수 길이 문자열

아래의 리스트의 요소들의 철자의 길이 중에 짝수인 것만 셋 자료형에 결과로 담아 출력하세요.

컴프리헨션을 사용하지 않았을 때:

words = ["apple", "banana", "cherry", "date", "apple", "banana", "elderberry"]

result = set()	# 중복제거
for word in words:
    if len(word) % 2 == 0:
        result.add(len(word))	# set함수에는 추가할 때 add 써야함
print(result)	# {4, 6, 10}

컴프리헨션을 사용했을 때: (⭐평가문제 5번)

words = ["apple", "banana", "cherry", "date", "apple", "banana", "elderberry"]

result = {len(word) for word in words if len(word) % 2 == 0}    # 중괄호{}가 set임
print(result)	# {4, 6, 10}

문제1. 작은 제곱수

다음 리스트에 있는 숫자들의 제곱 중에서 50보다 작은 값들만 셋으로 만드시오.

컴프리헨션을 사용하지 않았을 때:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = set()
for num in numbers:
    square = num ** 2
    if square < 50:
        result.add(square)
print(result)	# {1, 4, 9, 16, 25, 36, 49}

컴프리헨션을 사용했을 때:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = {num**2 for num in numbers if num**2 < 50}
print(result)   # {1, 4, 9, 16, 25, 36, 49}

✔️ 4. 문자열 처리 예제

예제1. 'a' 포함 문자열 찾기

주어진 리스트에서 각 문자열이 소문자 'a'를 포함하고 있는지 확인하고 포함하고 있는 문자열을 별도의 리스트에 담아 출력하시오.

컴프리헨션을 사용하지 않았을 때:

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'kiwi']

result = []
for i in words:
    if 'a' in i:
        result.append(i)

print(result)	# ['apple', 'banana', 'date', 'aricot']

컴프리헨션을 사용했을 때:

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'kiwi']

result = [i for i in words if 'a' in i]
print(result)   # ['apple', 'banana', 'date', 'aricot']

문제1. 긴 문자열 찾기

다음 리스트에서 길이가 5보다 큰 문자열만 선택하시오.

컴프리헨션을 사용하지 않았을 때:

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'kiwi']

result = []
for word in words:
    if len(word) > 5:
        result.append(word)
print(result)	# ['banana', 'cherry', 'aricot']

컴프리헨션을 사용했을 때:

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'kiwi']

result = [word for word in words if len(word) > 5]
print(result)   # ['banana', 'cherry', 'aricot']

문제2. 특정 문자로 시작하는 단어

다음 리스트에서 문자열의 첫 글자가 'a' 또는 'b'로 시작하는 것만 선택하시오.

컴프리헨션을 사용하지 않았을 때:

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'blueberry', 'kiwi']

result = []
for word in words:
    if word.startswith('a') or word.startswith('b'):
        result.append(word)
print(result)	# ['apple', 'banana', 'aricot', 'blueberry']

컴프리헨션을 사용했을 때:

startswith(): ()안에 있는 단어로 시작하라는 의미

words = ['apple', 'banana', 'cherry', 'date', 'aricot', 'blueberry', 'kiwi']

result = [word for word in words if word.startswith('a') or word.startswith('b')]
print(result)	# ['apple', 'banana', 'aricot', 'blueberry']

예제3. 모음 제거하기

컴프리헨션을 사용하지 않았을 때:

text = "Hello World"

result = ""		# 비어있는 문자열 변수 선언
for char in text:
    if char.lower() not in 'aeiou':
        result += char
print(result)	# "Hll Wrld"

컴프리헨션을 사용했을 때:

join(): 리스트의 요소를 함수로 바꿈

text = "Hello World"

result = ''.join([char for char in text if char.lower() not in 'aeiou'])
print(result)   # "Hll Wrld"

문제3. 숫자 추출하기

다음 문자열에서 숫자만 추출하여 리스트로 만드시오.

  • isdigit(): 숫자만 추출됨

컴프리헨션을 사용하지 않았을 때:

text = "a1b2c3d4e5"

result = []
for char in text:
    if char.isdigit():
        result.append(int(char))
print(result)	# [1, 2, 3, 4, 5]

컴프리헨션을 사용했을 때:

text = "a1b2c3d4e5"

result = [int(char) for char in text if char.isdigit()]
print(result)	# [1, 2, 3, 4, 5]

✔️ 5. 정렬 함수 예제

예제1. 리스트 정렬 함수

아래의 리스트를 받아서 정렬해서 출력하는 sort_list 함수를 생성하세요.
sorted(): 리스트 정렬함수

일반 함수 구현:

def sort_list(data):
    return sorted(data)

data = [5, 3, 8, 1, 4, 7, 2, 6]
sorted_list = sort_list(data)
print(sorted_list)	# [1, 2, 3, 4, 5, 6, 7, 8]

문제1. 내림차순 정렬 함수

리스트를 내림차순으로 정렬하는 함수를 작성하시오.

일반 방식:

def sort_desc(data):
    return sorted(data, reverse=True)

data = [5, 3, 8, 1, 4, 7, 2, 6]
sorted_list = sort_desc(data)
print(sorted_list)	# [8, 7, 6, 5, 4, 3, 2, 1]

✔️ 6. 컴프리헨션 사용 시 주의사항

⚠️ 주의할 점

1. 너무 복잡한 로직은 일반 루프로

가독성 떨어질 수 있음

# 나쁜 예 - 너무 복잡함
result = [process(x) for x in data if condition1(x) and condition2(x) and condition3(x)]

# 좋은 예 - 일반 루프 사용
result = []
for x in data:
    if condition1(x) and condition2(x) and condition3(x):
        result.append(process(x))

2. 중첩된 컴프리헨션 주의

이해하기 어려울 수 있음

# 나쁜 예 - 중첩이 복잡함
matrix = [[j for j in range(i)] for i in range(5)]

# 좋은 예 - 명확하게 분리
matrix = []
for i in range(5):
    row = [j for j in range(i)]
    matrix.append(row)

3. 딕셔너리 컴프리헨션에서 키는 유일해야 함

중복 키는 덮어써짐


✔️ 7. 핵심 정리

🎯 컴프리헨션의 핵심 가치

  • 간결성: 여러 줄의 코드를 한 줄로 표현
  • 가독성: 의도가 명확하게 드러나는 코드
  • 성능: 일반 루프보다 빠른 실행 속도
  • 파이써닉: 파이썬다운 코드 작성

📝 사용 가이드라인

  • 리스트 컴프리헨션: 새로운 리스트를 만들거나 기존 리스트를 변환할 때
  • 딕셔너리 컴프리헨션: 키-값 쌍을 필터링하거나 변환할 때
  • 셋 컴프리헨션: 중복 제거가 필요하거나 고유한 값이 필요할 때

0개의 댓글