Python Programming
  • Home
  • Intro
    • History & Background
    • Python Setup
  • QPB
    • Part I: Chapter 1-3
    • Part II
    • 5. Lists, Tuples, Sets
  • Exercises
    • Chapter 5: Lists, Tuples, Sets
    • Chapter 6: Strings
  • References
    • QPB Part 1
    • QPB Part 2
    • QPB Part 3
    • QPB Part 4

On this page

  • 문제 1: if-elif-else 조건문
  • 문제 2: match-case 패턴 매칭
  • 문제 3: while 루프와 break/continue
  • 문제 4: for 루프와 range
  • 문제 5: enumerate를 활용한 인덱스와 값 처리
  • 문제 6: zip을 활용한 병렬 처리
  • 문제 7: 리스트 컴프리헨션 (List Comprehension)
  • 문제 8: 딕셔너리 컴프리헨션 (Dictionary Comprehension)
  • 문제 9: 중첩 루프와 패턴 출력
  • 문제 10: Boolean 표현식과 조건부 로직
  • 문제 11**: 제너레이터와 메모리 효율적인 데이터 처리

Exercises: Chapter 8

Chapter 8: Control Flow - 연습문제

문제 1: if-elif-else 조건문

사용자의 점수를 입력받아 학점을 출력하는 프로그램을 작성하세요.

학점 기준:

  • 90점 이상: A
  • 80점 이상 90점 미만: B
  • 70점 이상 80점 미만: C
  • 60점 이상 70점 미만: D
  • 60점 미만: F

추가 요구사항:

  • 점수가 0 미만이거나 100 초과인 경우 “Invalid score” 출력
  • A 또는 B 학점인 경우 “Excellent!” 메시지 추가

힌트: if-elif-else 구조와 논리 연산자(and, or)를 사용하세요.

# 여기에 코드를 작성하세요
score = 85  # 다른 값으로도 테스트해보세요

문제 2: match-case 패턴 매칭

다음 작업을 수행하는 함수를 작성하세요:

commands = ["start", "stop", "pause", "resume", 5, "quit", "unknown"]

각 명령에 대해 match-case를 사용하여 다음을 프린트:

  • “start”: “Starting the system…”
  • “stop” 또는 “quit”: “Stopping the system…”
  • “pause”: “Pausing the system…”
  • “resume”: “Resuming the system…”
  • 정수(int): “Received number: {숫자}”
  • 기타: “Unknown command: {명령}”

힌트: match-case 구문에서 | 연산자로 여러 케이스를 동시에 처리하고, int()로 타입 매칭을 사용하세요.

# 여기에 코드를 작성하세요
commands = ["start", "stop", "pause", "resume", 5, "quit", "unknown"]

문제 3: while 루프와 break/continue

사용자로부터 숫자를 계속 입력받아 합계를 계산하는 프로그램을 작성하세요.

요구사항:

  1. 사용자가 “done”을 입력하면 루프 종료
  2. 음수를 입력하면 “Negative numbers are not allowed” 메시지 출력 후 건너뛰기 (continue)
  3. 0을 입력하면 “Zero entered, stopping…” 메시지 출력 후 루프 종료 (break)
  4. 정상 종료(“done” 입력)시 else 블록에서 “Sum completed normally” 출력
  5. break로 종료시 else 블록 실행 안됨

힌트: while True, break, continue, else를 활용하세요. 이 문제는 실제 input() 대신 미리 정의된 리스트로 시뮬레이션하세요.

# 여기에 코드를 작성하세요
# 실제 input() 대신 미리 정의된 입력 사용
inputs = ["5", "10", "-3", "7", "done"]  # 또는 ["5", "10", "0", "7"]로 테스트

문제 4: for 루프와 range

다음 작업을 수행하세요:

  1. 1부터 20까지의 숫자 중 짝수만 출력 (range 사용)
  2. 10부터 1까지 역순으로 출력 (range 사용)
  3. 구구단 7단 출력 (7 x 1 = 7부터 7 x 9 = 63까지)
  4. 1부터 100까지의 숫자 중 3의 배수이면서 5의 배수인 숫자들의 합 계산

힌트: range(start, stop, step)의 세 가지 매개변수를 활용하세요.

# 여기에 코드를 작성하세요

# 1. 1부터 20까지 짝수


# 2. 10부터 1까지 역순


# 3. 구구단 7단


# 4. 3의 배수이면서 5의 배수인 숫자들의 합

문제 5: enumerate를 활용한 인덱스와 값 처리

다음 온도 데이터에서:

temperatures = [22, 25, 19, -999, 23, -999, 21, 24]

다음 작업을 수행하세요:

  1. -999는 측정 실패를 의미합니다. 모든 -999를 유효한 온도들의 평균값으로 교체
  2. 교체할 때마다 “인덱스 {i}의 값을 {평균값}으로 수정” 메시지 출력
  3. 수정된 전체 온도 리스트 출력
  4. 20도 이상인 온도들의 인덱스와 값을 출력

힌트: enumerate() 함수를 사용하고, 리스트 컴프리헨션으로 유효한 값만 필터링하세요.

# 여기에 코드를 작성하세요
temperatures = [22, 25, 19, -999, 23, -999, 21, 24]

문제 6: zip을 활용한 병렬 처리

세 반의 학생 점수가 다음과 같이 주어집니다:

names = ["Alice", "Bob", "Charlie", "David", "Eve"]
math_scores = [85, 92, 78, 95, 88]
english_scores = [90, 85, 92, 88, 95]

다음 작업을 수행하세요:

  1. zip을 사용하여 각 학생의 이름, 수학 점수, 영어 점수를 동시에 출력
  2. 각 학생의 평균 점수 계산하여 출력
  3. 평균이 90점 이상인 학생에게는 “Excellent!” 메시지 추가
  4. 모든 학생의 정보를 딕셔너리 리스트로 저장 (키: name, math, english, average)

힌트: zip() 함수로 세 리스트를 동시에 순회하세요.

# 여기에 코드를 작성하세요
names = ["Alice", "Bob", "Charlie", "David", "Eve"]
math_scores = [85, 92, 78, 95, 88]
english_scores = [90, 85, 92, 88, 95]

문제 7: 리스트 컴프리헨션 (List Comprehension)

다음 작업을 리스트 컴프리헨션으로 수행하세요:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
words = ["apple", "banana", "cherry", "date", "elderberry", "fig"]
  1. numbers에서 짝수의 제곱만 추출 → [4, 16, 36, 64, 100]
  2. numbers에서 홀수는 제곱, 짝수는 음수로 변환 → [1, -2, 9, -4, 25, -6, 49, -8, 81, -10]
  3. words에서 5글자 이상인 단어만 대문자로 변환
  4. words의 각 단어의 길이로 리스트 생성 → [5, 6, 6, 4, 10, 3]
  5. 1부터 50까지 중 3으로 나누어떨어지지만 5로는 나누어떨어지지 않는 숫자 리스트

힌트: [표현식 for 변수 in 시퀀스 if 조건], [표현식1 if 조건 else 표현식2 for 변수 in 시퀀스]

# 여기에 코드를 작성하세요
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
words = ["apple", "banana", "cherry", "date", "elderberry", "fig"]

# 1. 짝수의 제곱


# 2. 홀수는 제곱, 짝수는 음수


# 3. 5글자 이상 단어를 대문자로


# 4. 각 단어의 길이


# 5. 3의 배수이지만 5의 배수가 아닌 숫자

문제 8: 딕셔너리 컴프리헨션 (Dictionary Comprehension)

다음 작업을 딕셔너리 컴프리헨션으로 수행하세요:

students = ["Alice", "Bob", "Charlie", "David"]
scores = [85, 92, 78, 95]
products = {"apple": 1.20, "banana": 0.50, "cherry": 3.00, "date": 2.50}
  1. students와 scores를 zip으로 묶어 {이름: 점수} 딕셔너리 생성
  2. 위 딕셔너리에서 점수가 80점 이상인 학생만 필터링
  3. products에서 가격이 2.00 이상인 제품만 필터링하고, 가격을 10% 할인
  4. 1부터 10까지 숫자를 키로, 제곱을 값으로 하는 딕셔너리 생성
  5. products의 키와 값을 바꾸기 (가격이 키, 제품명이 값)

힌트: {키표현식: 값표현식 for 변수 in 시퀀스 if 조건}

# 여기에 코드를 작성하세요
students = ["Alice", "Bob", "Charlie", "David"]
scores = [85, 92, 78, 95]
products = {"apple": 1.20, "banana": 0.50, "cherry": 3.00, "date": 2.50}

# 1. 이름-점수 딕셔너리


# 2. 80점 이상만 필터링


# 3. 2.00 이상 제품만 10% 할인


# 4. 숫자와 제곱


# 5. 키-값 바꾸기

문제 9: 중첩 루프와 패턴 출력

다음 패턴들을 중첩 루프를 사용하여 출력하세요:

패턴 1: 직각 삼각형

*
**
***
****
*****

패턴 2: 역 직각 삼각형

*****
****
***
**
*

패턴 3: 피라미드

    *
   ***
  *****
 *******
*********

패턴 4: 구구단 테이블 (2단~5단, 1~5까지만)

2x1=2  3x1=3  4x1=4  5x1=5  
2x2=4  3x2=6  4x2=8  5x2=10 
...

힌트: 중첩 for 루프와 print()의 end 매개변수를 활용하세요.

# 여기에 코드를 작성하세요

# 패턴 1: 직각 삼각형
print("패턴 1:")


# 패턴 2: 역 직각 삼각형
print("\n패턴 2:")


# 패턴 3: 피라미드
print("\n패턴 3:")


# 패턴 4: 구구단 테이블
print("\n패턴 4:")

문제 10: Boolean 표현식과 조건부 로직

다음 데이터에 대해 복잡한 조건 로직을 구현하세요:

users = [
    {"name": "Alice", "age": 25, "premium": True, "login_count": 150},
    {"name": "Bob", "age": 17, "premium": False, "login_count": 50},
    {"name": "Charlie", "age": 30, "premium": True, "login_count": 300},
    {"name": "David", "age": 22, "premium": False, "login_count": 200},
    {"name": "Eve", "age": 16, "premium": False, "login_count": 80},
]

다음 조건에 따라 사용자를 분류하세요:

  1. VIP: 나이 18세 이상 AND premium True AND login_count >= 200
  2. Active: 나이 18세 이상 AND login_count >= 100 (VIP 제외)
  3. Regular: 나이 18세 이상 (VIP, Active 제외)
  4. Minor: 나이 18세 미만

각 사용자에 대해 “이름: 등급” 형태로 출력하고, 각 등급별 인원수를 계산하세요.

힌트: and, or, not 연산자와 복합 조건문을 사용하세요. 조건 순서가 중요합니다!

# 여기에 코드를 작성하세요
users = [
    {"name": "Alice", "age": 25, "premium": True, "login_count": 150},
    {"name": "Bob", "age": 17, "premium": False, "login_count": 50},
    {"name": "Charlie", "age": 30, "premium": True, "login_count": 300},
    {"name": "David", "age": 22, "premium": False, "login_count": 200},
    {"name": "Eve", "age": 16, "premium": False, "login_count": 80},
]

문제 11**: 제너레이터와 메모리 효율적인 데이터 처리

대용량 데이터를 처리하는 시나리오를 시뮬레이션하세요.

상황: 1부터 1,000,000까지의 숫자 중에서:

  1. 소수(prime number)만 추출
  2. 추출된 소수의 제곱을 계산
  3. 제곱값이 1,000,000 이하인 것만 선택
  4. 최종 결과의 합계 계산

요구사항:

  • 제너레이터 함수를 사용하여 메모리 효율적으로 구현
  • 리스트 컴프리헨션 버전과 제너레이터 표현식 버전을 모두 구현하여 비교
  • 각 단계별로 제너레이터를 체이닝(chaining)하여 파이프라인 구축

출력 예시:

소수의 개수: 168
조건을 만족하는 제곱값의 합계: 10000000
def is_prime(n):
    """
    주어진 숫자가 소수인지 판별합니다.
    
    Args:
        n: 판별할 숫자
    
    Returns:
        bool: 소수이면 True, 아니면 False
    """
    if n < 2:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    
    # 힌트: n의 제곱근까지만 확인하면 됩니다
    for i in range(3, int(n**0.5) + 1, 2):
        if n % i == 0:
            return False
    return True


def prime_generator(max_num):
    """
    max_num까지의 소수를 생성하는 제너레이터
    
    Args:
        max_num: 최대 숫자
    
    Yields:
        int: 소수
    """
    # 힌트: for 루프로 숫자를 순회하면서 is_prime()으로 체크
    # yield를 사용하여 소수를 하나씩 반환
    for num in range(2, max_num + 1):
        if is_prime(num):
            ...  # 여기에 yield 구문 작성


# 1. 제너레이터 함수 버전
def process_with_generator(max_num, square_limit):
    """
    제너레이터를 사용하여 데이터를 처리합니다.
    """
    # 힌트: prime_generator()로 소수를 얻고
    # 제곱을 계산하고 조건을 체크하여 sum() 계산
    primes = prime_generator(max_num)
    
    # 제너레이터 표현식으로 제곱 계산 및 필터링
    squared_primes = (p**2 for p in primes if p**2 <= square_limit)
    
    # 결과 계산
    ...  # sum()을 사용하여 합계 계산


# 2. 리스트 컴프리헨션 버전 (비교용 - 메모리 많이 사용)
def process_with_list(max_num, square_limit):
    """
    리스트 컴프리헨션을 사용하여 데이터를 처리합니다.
    (메모리를 더 많이 사용함)
    """
    # 힌트: 리스트 컴프리헨션으로 모든 소수를 먼저 생성
    primes = [n for n in range(2, max_num + 1) if is_prime(n)]
    
    # 제곱 계산 및 필터링
    squared_primes = [p**2 for p in primes if p**2 <= square_limit]
    
    return sum(squared_primes), len(primes)


# 테스트 (작은 숫자로 먼저 테스트)
print("=== 작은 범위 테스트 (1-100) ===")
result_gen = process_with_generator(100, 10000)
result_list, prime_count = process_with_list(100, 10000)

print(f"제너레이터 버전 합계: {result_gen}")
print(f"리스트 버전 합계: {result_list}")
print(f"소수 개수: {prime_count}")

# 실제 문제 (큰 범위)
# 주의: 이 코드는 실행에 시간이 걸릴 수 있습니다
# print("\n=== 실제 문제 (1-1,000,000) ===")
# result = process_with_generator(1000000, 1000000)
# print(f"최종 합계: {result}")
Chapter 7: Dictionaries

This work © 2025 by Sungkyun Cho is licensed under CC BY-NC-SA 4.0