본문 바로가기

Python

7-1. 리스트/딕셔너리 컴프리헨션 심화

파이썬 리스트/딕셔너리 컴프리헨션 심화

안녕하세요! 지난 시간에는 객체지향 프로그래밍(OOP)의 마지막 개념인 추상 클래스와 인터페이스에 대해 알아보았습니다. 이제 여러분은 프로그램을 더욱 체계적이고 확장 가능하게 설계하는 방법을 이해하셨을 거예요.

이번 시간부터는 파이썬의 고급 문법과 실전 예제들을 통해 여러분의 코딩 실력을 한 단계 더 높여보겠습니다. 그 첫 번째 주제는 바로 리스트/딕셔너리 내포 표현식(Comprehension)의 심화 활용입니다.

이전에 '3-6. 리스트/딕셔너리 내포 표현식'에서 기본적인 사용법을 배웠지만, 내포 표현식은 단순한 반복문을 넘어 더욱 복잡한 조건과 중첩 구조를 간결하게 표현할 수 있는 강력한 기능입니다. 이 심화 내용을 익히면 여러분의 코드가 훨씬 더 "파이썬스럽고(Pythonic)" 효율적으로 변할 것입니다.


Part 1: 리스트 내포 심화 (Advanced List Comprehension)

리스트 내포는 [표현식 for 항목 in 반복_가능한_객체] 또는 [표현식 for 항목 in 반복_가능한_객체 if 조건] 형태로 사용했습니다. 이제 여기에 더 복잡한 조건이나 중첩을 추가하는 방법을 알아봅시다.

1. 조건부 표현식 (if-else) 포함: [표현식 if 조건 else 다른_표현식 for 항목 in 반복_가능한_객체]

  • 설명: 각 항목에 대해 조건을 검사하여, 조건이 True이면 첫 번째 표현식을, False이면 else 뒤의 다른_표현식을 적용합니다. if와 else가 함께 사용될 때는 for 문 에 위치해야 합니다.

예시: 숫자가 짝수면 제곱, 홀수면 그대로 두기

Python
 
# 파일 이름: list_comp_if_else.py

numbers = [1, 2, 3, 4, 5, 6]

# 일반적인 for 문과 if-else
processed_numbers_normal = []
for num in numbers:
    if num % 2 == 0:
        processed_numbers_normal.append(num ** 2)
    else:
        processed_numbers_normal.append(num)
print(f"일반 for-if-else: {processed_numbers_normal}")

# 리스트 내포 (if-else 포함)
processed_numbers_comp = [num ** 2 if num % 2 == 0 else num for num in numbers]
print(f"리스트 내포 (if-else): {processed_numbers_comp}")

# 점수에 따라 '합격' 또는 '불합격' 문자열 생성
scores = [85, 55, 90, 70, 40]
results = ["합격" if score >= 60 else "불합격" for score in scores]
print(f"점수 결과: {results}")

 

[VS Code 터미널 출력]

파이썬 리스트 내포에 if-else 조건부 표현식 포함 예시

2. 중첩 조건 (if 여러 개): [표현식 for 항목 in 반복_가능한_객체 if 조건1 if 조건2]

  • 설명: if 문을 여러 개 연속해서 붙이면 and 조건처럼 작동합니다. 모든 if 조건이 True일 때만 해당 항목이 선택됩니다. if는 for 문 에 위치합니다.

예시: 1부터 20까지 숫자 중 짝수이면서 5의 배수인 숫자만 선택

Python
 
# 파일 이름: list_comp_nested_if.py

numbers = range(1, 21) # 1부터 20까지

# 일반적인 for 문과 중첩 if
filtered_normal = []
for num in numbers:
    if num % 2 == 0: # 짝수
        if num % 5 == 0: # 5의 배수
            filtered_normal.append(num)
print(f"일반 for-if-if: {filtered_normal}")

# 리스트 내포 (중첩 if)
filtered_comp = [num for num in numbers if num % 2 == 0 if num % 5 == 0]
print(f"리스트 내포 (중첩 if): {filtered_comp}")

# 또는 논리 연산자 `and` 사용 (동일한 결과)
filtered_and = [num for num in numbers if num % 2 == 0 and num % 5 == 0]
print(f"리스트 내포 (and): {filtered_and}")

 

[VS Code 터미널 출력]

파이썬 리스트 내포에 중첩 if 조건 사용 예시

3. 여러 for 문과 if 조합: [표현식 for 항목1 in 반복1 if 조건1 for 항목2 in 반복2 if 조건2]

  • 설명: 여러 개의 for 루프와 if 조건을 조합하여 복잡한 리스트를 생성할 수 있습니다. 중첩 for 문과 동일하게 바깥쪽 for부터 순서대로 실행됩니다.

예시: 두 리스트에서 합이 10이 되는 모든 쌍 찾기

Python
 
# 파일 이름: list_comp_multi_for_if.py

list1 = [1, 2, 3, 4]
list2 = [6, 7, 8, 9]

# 일반적인 중첩 for 문과 if
pairs_normal = []
for x in list1:
    for y in list2:
        if x + y == 10:
            pairs_normal.append((x, y))
print(f"일반 중첩 for-if: {pairs_normal}")

# 리스트 내포 (여러 for 문과 if 조합)
pairs_comp = [(x, y) for x in list1 for y in list2 if x + y == 10]
print(f"리스트 내포 (복합): {pairs_comp}")

# 문자열 리스트에서 'a'와 'b'로 시작하는 모든 조합 생성
chars1 = ['a', 'b', 'c']
chars2 = ['x', 'y', 'z']
combinations = [c1 + c2 for c1 in chars1 if c1 in ['a', 'b'] for c2 in chars2 if c2 in ['x', 'y']]
print(f"문자열 조합: {combinations}")

 

[VS Code 터미널 출력]

파이썬 리스트 내포에 여러 for 문과 if 조건 조합 예시

Part 2: 딕셔너리 내포 심화 (Advanced Dictionary Comprehension)

딕셔너리 내포도 리스트 내포와 유사하게 if-else 조건이나 다른 딕셔너리를 기반으로 복잡한 딕셔너리를 생성할 수 있습니다.

1. 조건부 표현식 (if-else) 포함: {키_표현식: (값_표현식 if 조건 else 다른_값_표현식) for 항목 in 반복_가능한_객체}

  • 설명: 딕셔너리의 값 부분에 if-else 조건부 표현식을 사용하여, 조건에 따라 다른 값을 할당할 수 있습니다.

예시: 점수에 따라 등급을 부여하는 딕셔너리 생성

Python
 
# 파일 이름: dict_comp_if_else.py

student_scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 60, "Eve": 95}

# 일반적인 for 문과 if-else
student_grades_normal = {}
for name, score in student_scores.items():
    if score >= 90:
        student_grades_normal[name] = "A"
    elif score >= 80:
        student_grades_normal[name] = "B"
    else:
        student_grades_normal[name] = "C"
print(f"일반 for-if-else: {student_grades_normal}")

# 딕셔너리 내포 (if-elif-else는 한 줄로 직접 표현하기 어려우므로, if-else를 중첩하거나 함수 사용)
# 여기서는 간단한 if-else로 90점 이상 A, 아니면 B
student_grades_comp = {name: ("A" if score >= 90 else "B") for name, score in student_scores.items()}
print(f"딕셔너리 내포 (간단 if-else): {student_grades_comp}")

# 더 복잡한 조건은 함수를 사용하는 것이 가독성에 좋습니다.
def get_grade(score):
    if score >= 90: return "A"
    elif score >= 80: return "B"
    else: return "C"

student_grades_with_func = {name: get_grade(score) for name, score in student_scores.items()}
print(f"딕셔너리 내포 (함수 사용): {student_grades_with_func}")

 

[VS Code 터미널 출력]

파이썬 딕셔너리 내포에 if-else 조건부 표현식 포함 예시

2. 기존 딕셔너리에서 필터링/변환: {키: 값 for 키, 값 in 딕셔너리.items() if 조건}

  • 설명: 기존 딕셔너리의 items() 메서드를 순회하면서 특정 조건에 맞는 키: 값 쌍만 선택하여 새로운 딕셔너리를 만들 수 있습니다.

예시: 특정 점수 이상의 학생만 포함하는 딕셔너리 만들기

Python
 
# 파일 이름: dict_comp_filter.py

student_scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 60, "Eve": 95}

# 80점 이상인 학생만 필터링 (일반 for 문)
passed_students_normal = {}
for name, score in student_scores.items():
    if score >= 80:
        passed_students_normal[name] = score
print(f"일반 for-if: {passed_students_normal}")

# 딕셔너리 내포 (필터링)
passed_students_comp = {name: score for name, score in student_scores.items() if score >= 80}
print(f"딕셔너리 내포 (필터링): {passed_students_comp}")

# 가격이 50000원 이상인 제품만 선택하고, 가격을 10% 할인하여 새로운 딕셔너리 생성
products = {"노트북": 1200000, "마우스": 25000, "키보드": 70000, "모니터": 300000}
discounted_products = {
    name: price * 0.9
    for name, price in products.items()
    if price >= 50000
}
print(f"할인된 고가 제품: {discounted_products}")

 

[VS Code 터미널 출력]

파이썬 딕셔너리 내포로 필터링 및 변환 예시

마무리하며

이번 시간에는 **리스트 내포(List Comprehension)**와 **딕셔너리 내포(Dictionary Comprehension)**의 심화된 활용법에 대해 알아보았습니다.

  • 리스트 내포:
    • if-else 조건부 표현식을 for 앞에 사용하여 값 자체를 조건에 따라 다르게 생성.
    • 여러 if 조건을 for 뒤에 붙여 중첩 필터링.
    • 여러 for 문을 중첩하여 복합적인 리스트 생성.
  • 딕셔너리 내포:
    • 값 부분에 if-else 조건부 표현식을 사용하여 조건에 따라 다른 값 할당.
    • 기존 딕셔너리를 순회하며 필터링하거나 값을 변환하여 새로운 딕셔너리 생성.

내포 표현식은 파이썬의 강력한 기능 중 하나로, 코드를 간결하고 효율적으로 만들 수 있습니다. 처음에는 복잡하게 느껴질 수 있지만, 꾸준히 연습하면 파이썬 코딩의 생산성을 크게 높일 수 있을 것입니다.

다음 포스팅에서는 파이썬의 메모리 효율적인 데이터 생성 방법인 **제너레이터(Generator)**와 yield 키워드에 대해 알아보겠습니다.


궁금한 점이 있다면 언제든지 질문해주세요! 다음 포스팅에서 만나요!

반응형