americano = 2500 # 아메리카노 가격(원)
latte = 3500 # 카페라떼 가격(원)
print(americano < latte)
print(americano > latte)
print(americano == latte)
print(type(americano < latte))True
False
False
<class 'bool'>
이번 장의 주제는 조건문입니다. 프로그램이 상황을 보고 스스로 갈림길을 고르게 만드는 문법입니다. 장을 마칠 때 여러분이 손에 쥐게 될 것은 다음과 같습니다.
if, elif, else가 실행 흐름을 어떻게 갈라놓는지 이해합니다.IndentationError와 SyntaxError 메시지를 읽는 요령을 배웁니다.경제학원론 첫 시간에 누구나 듣는 문장이 있습니다. 경제학은 선택의 학문이라는 말입니다. 시험 기간의 이콘 카페를 떠올려 보면 이 말이 꽤 구체적으로 다가옵니다. 아메리카노 한 잔을 비웠는데 아직 공부할 분량이 남았습니다. 한 잔 더 시킬까요? 경제학은 이 고민을 깔끔하게 정리합니다. 두 번째 잔이 주는 만족, 즉 한계편익이 두 번째 잔의 가격 2,500원보다 크면 마시고, 작으면 멈춘다. 첫 잔의 만족이 아무리 컸어도 소용없습니다. 갈림길에서 중요한 것은 언제나 “다음 한 단위”입니다.
그런데 지난 두 장에서 우리가 쓴 코드를 돌아보면, 전부 위에서 아래로 한 줄씩 예외 없이 실행되는 코드였습니다. 계산은 잘했지만 선택은 한 번도 하지 못했습니다. “만약 ~라면”이라는 갈림길이 없었기 때문입니다. 이번 장의 주인공인 조건문(conditional statement)이 바로 그 갈림길을 코드에 심는 문법입니다.
갈림길 하나가 뭐 그리 대단한가 싶을 수 있지만, 장 후반부에서 확인하게 될 것입니다. 이 문법 하나로 한국 소득세의 여덟 개 누진 구간을 계산기 하나에 담을 수 있고, “연봉이 오르면 세금 구간이 바뀌어서 오히려 손해”라는 흔한 오해를 숫자로 반박할 수 있으며, 최저임금이 시장에서 언제 실제로 힘을 발휘하는지도 판정할 수 있습니다.
갈림길을 만들려면 먼저 “조건”을 컴퓨터가 알아듣는 형태로 써야 합니다. 파이썬에서 조건의 답은 언제나 둘 중 하나입니다. 참이면 True, 거짓이면 False. 2장에서 자료형을 훑을 때 잠깐 스쳤던 불리언(bool)이 이번 장의 실질적인 주인공입니다.
불리언 값을 만드는 가장 흔한 방법은 두 값을 비교하는 것입니다. 이콘 카페의 메뉴판으로 시작해 보겠습니다.
americano = 2500 # 아메리카노 가격(원)
latte = 3500 # 카페라떼 가격(원)
print(americano < latte)
print(americano > latte)
print(americano == latte)
print(type(americano < latte))True
False
False
<class 'bool'>
americano < latte는 계산식입니다. 다만 결과가 숫자가 아니라 True라는 불리언 값일 뿐입니다. 마지막 줄의 type()이 그 사실을 확인해 줍니다. 파이썬이 제공하는 비교 연산자는 여섯 개입니다.
| 연산자 | 뜻 | 예 (a = 10, b = 5) |
결과 |
|---|---|---|---|
== |
같다 | a == 10 |
True |
!= |
다르다 | a != b |
True |
> |
크다 | a > b |
True |
< |
작다 | a < b |
False |
>= |
크거나 같다 | a >= 10 |
True |
<= |
작거나 같다 | b <= 4 |
False |
여기서 눈에 익혀 둘 것은 “같다”가 등호 두 개(==)라는 점입니다. 등호 하나(=)는 2장부터 써 온 할당, 즉 “오른쪽 값을 왼쪽 이름에 담아라”는 명령이므로 완전히 다른 기호입니다. 이 둘을 혼동했을 때 무슨 일이 생기는지는 잠시 뒤 실수 노트에서 따로 다룹니다.
비교는 숫자에만 쓰는 것이 아닙니다. 문자열끼리도 같은지 다른지 비교할 수 있습니다.
menu = "아메리카노"
print(menu == "아메리카노")
print(menu != "카페라떼")
print(2500 >= 2500)
print(2500 > 2500)True
True
True
False
마지막 두 줄을 비교해 보면 >=와 >의 차이가 드러납니다. 값이 딱 경계에 걸렸을 때 등호가 포함되는지 아닌지는 사소해 보이지만, 소득세 구간처럼 경계가 돈이 되는 문제에서는 결과를 바꾸는 차이입니다. 이제 이 불리언 값을 실제 갈림길로 바꿔 보겠습니다.
조건문의 가장 단순한 형태는 if 하나만 있는 구조입니다.
if 조건식:
조건식이 True일 때만 실행되는 블록
그 아래는 조건과 무관하게 항상 실행
규칙은 세 가지입니다. if 뒤에 불리언 값이 나오는 조건식을 쓰고, 그 줄을 콜론(:)으로 끝내고, 조건이 참일 때 실행할 줄들을 들여 씁니다. 체크카드 잔액으로 커피를 살 수 있는지 판정해 보겠습니다.
balance = 4000 # 체크카드 잔액(원)
price = 2500 # 아메리카노 한 잔 값(원)
if balance >= price:
print("잔액이 충분합니다. 주문을 진행합니다.")
print("판정이 끝났습니다.")잔액이 충분합니다. 주문을 진행합니다.
판정이 끝났습니다.
balance = 4000 / price = 2500 — 2장에서 배운 그대로, 판단에 쓸 재료를 변수에 담았습니다.if balance >= price: — 갈림길의 입구입니다. balance >= price가 먼저 계산되어 True가 되고, if는 그 값을 보고 아래 블록을 실행할지 결정합니다. 줄 끝의 콜론은 “이제 블록이 시작된다”는 신호이며, 빠뜨리면 SyntaxError가 납니다.print("잔액이 충분합니다. ...") — 앞에 공백 네 칸이 있습니다. 이 들여쓰기가 “이 줄은 if에 속한다”는 표시입니다. 조건이 거짓이었다면 이 줄은 통째로 건너뜁니다.print("판정이 끝났습니다.") — 들여쓰기가 없으므로 if 바깥의 줄입니다. 조건과 상관없이 항상 실행됩니다. 시험 삼아 balance를 2000으로 바꿔 다시 실행해 보면, 첫 번째 문장만 사라지고 이 줄은 그대로 출력됩니다.들여쓰기 이야기를 조금 더 해야겠습니다. 다른 여러 언어는 블록을 중괄호 { }로 감싸고 들여쓰기는 보기 좋으라고 하는 장식입니다. 파이썬은 다릅니다. 들여쓰기 자체가 문법입니다. 같은 블록에 속한 줄들은 같은 깊이로 들여 써야 하고, 관례는 공백 네 칸입니다. Colab과 대부분의 편집기는 콜론 뒤에서 줄을 바꾸면 자동으로 네 칸을 넣어 주므로 평소에는 신경 쓸 일이 적지만, 코드를 복사해 붙이다가 깊이가 어긋나는 순간 파이썬은 바로 항의합니다.
실수 노트: 들여쓰기를 잊었을 때 — IndentationError
조건문을 처음 배우는 주에 가장 자주 만나는 오류입니다. 콜론까지 잘 쓰고, 다음 줄을 들여 쓰지 않으면 어떻게 될까요.
balance = 4000
price = 2500
if balance >= price:
print("잔액이 충분합니다.")실행하면 파이썬은 코드를 시작하기도 전에 이런 메시지를 냅니다.
File "...", line 5
print("잔액이 충분합니다.")
^
IndentationError: expected an indented block after 'if' statement on line 4
에러 메시지는 아래에서 위로 읽는 것이 요령입니다. 마지막 줄이 결론입니다. 오류의 이름(IndentationError)과 설명(“4행의 if 문 다음에 들여쓰기된 블록이 와야 한다”)이 그대로 적혀 있습니다. 그 위의 line 5와 화살표(^)는 파이썬이 문제를 발견한 위치입니다. 반대 상황도 있습니다. if도 없는데 갑자기 들여 쓰면 IndentationError: unexpected indent, 즉 “예상 못 한 들여쓰기”라는 메시지가 나옵니다. 둘 다 이름이 원인을 말해 주는 친절한 오류이니, 만나면 당황하지 말고 들여쓰기 깊이부터 확인하면 됩니다.
실수 노트: =와 == — 한 글자 차이로 문법 오류
비교 연산자 표에서 예고한 실수입니다. “기준금리가 3.5인가?”를 물으려다 등호를 하나만 쓰면 이렇게 됩니다.
base_rate = 3.5 # 기준금리(%)
if base_rate = 3.5:
print("기준금리가 목표 수준과 같습니다.") File "...", line 3
if base_rate = 3.5:
^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
최근 버전의 파이썬은 “혹시 ==를 쓰려던 것 아니냐”고 되물어 줄 정도로 흔한 실수입니다(버전에 따라 메시지가 조금 다를 수 있습니다). 외우는 방법은 간단합니다. =는 담는 것, ==는 묻는 것. if 뒤는 언제나 질문하는 자리이므로 ==가 옵니다. 반대로 변수를 만들 자리에 ==를 쓰면 오류는 나지 않지만 값이 저장되지 않는, 더 찾기 어려운 문제가 생기니 방향을 바꿔서도 조심해야 합니다.
if만 있으면 조건이 거짓일 때 프로그램은 아무 말 없이 지나갑니다. 갈림길의 양쪽에 모두 할 일을 주려면 else를 붙입니다. 여는 질문에서 미뤄 둔 “한 잔 더” 문제를 이제 코드로 답할 수 있습니다. 시험공부 세 시간째, 두 번째 아메리카노가 주는 만족을 돈으로 환산하면 1,800원쯤 된다고 해 보겠습니다.
marginal_benefit = 1800 # 두 번째 잔이 주는 만족(원어치)
price = 2500 # 두 번째 잔의 가격(원)
if marginal_benefit >= price:
print("한계편익이 가격 이상입니다. 한 잔 더 마시는 편이 낫습니다.")
else:
print("한계편익이 가격에 못 미칩니다. 여기서 멈추는 편이 합리적입니다.")한계편익이 가격에 못 미칩니다. 여기서 멈추는 편이 합리적입니다.
else에는 조건식을 쓰지 않습니다. “위의 조건이 거짓이었던 모든 경우”가 자동으로 else의 몫이기 때문입니다. 그래서 if와 else 중 정확히 한쪽 블록만 실행됩니다.
경제학의 눈으로 다시 보면, 이 여섯 줄이 바로 한계 원리(marginal principle)입니다. 첫 잔이 5,000원어치 만족을 줬다는 사실은 코드 어디에도 등장하지 않습니다. 합리적 선택에서 이미 지나간 만족은 다음 잔의 판단 재료가 아니기 때문입니다. marginal_benefit을 3,000으로 바꿔 다시 실행해 보면 판정이 뒤집힙니다. 조건문은 이렇게 “기준은 그대로 두고 상황만 바꿔 가며” 판단을 반복할 수 있게 해 줍니다.
이번에는 여러분 차례입니다. 배달 앱에서 늘 하는 계산을 조건문으로 옮겨 보겠습니다.
# TODO: 변수 food_price = 12000 (담아 둔 음식 가격), min_order = 15000 (무료 배달 최소주문금액)을 만드세요.
# 1) food_price가 min_order 이상이면 "배달비 무료"를 출력합니다.
# 2) 그렇지 않으면 "무료 배달까지 XXXX원 남았습니다"를 f-string으로 출력합니다.
# 값을 바꿔 가며 두 갈래가 모두 잘 작동하는지 확인해 보세요.살 수 있다/없다, 마신다/멈춘다처럼 갈래가 둘이면 if와 else로 충분합니다. 그런데 경제 뉴스는 세상을 둘로만 나누지 않습니다. 성장률이 나오면 고성장인지, 그저 그런지, 침체인지 구간으로 말합니다. 갈래가 셋 이상일 때 쓰는 것이 elif(else if의 줄임)입니다.
if 조건식1:
조건식1이 True일 때
elif 조건식2:
조건식1은 False, 조건식2가 True일 때
elif 조건식3:
위 둘 다 False, 조건식3이 True일 때
else:
전부 False일 때
어느 해의 성장률 하나를 놓고 경기 국면을 분류해 보겠습니다.
growth_rate = -0.8 # 어느 해의 GDP 성장률(%)
if growth_rate >= 3.0:
phase = "고성장"
elif growth_rate >= 1.0:
phase = "중성장"
elif growth_rate > -1.0:
phase = "저성장"
else:
phase = "경기 후퇴"
print(f"성장률 {growth_rate}% → '{phase}' 국면")성장률 -0.8% → '저성장' 국면
if growth_rate >= 3.0: — 첫 관문입니다. -0.8은 3.0 이상이 아니므로 거짓, 아래 블록을 건너뛰고 다음 관문으로 갑니다.elif growth_rate >= 1.0: — 이 줄에는 겉으로 드러나지 않은 전제가 숨어 있습니다. 여기까지 왔다는 것 자체가 “3.0 이상은 아니다”라는 뜻이므로, 이 조건은 사실상 “1.0 이상 3.0 미만”을 검사하는 셈입니다. 그래서 growth_rate < 3.0을 따로 쓸 필요가 없습니다.elif growth_rate > -1.0: — 같은 논리로 “-1.0 초과 1.0 미만” 구간을 맡습니다. -0.8이 여기서 참이 되어 phase에 “저성장”이 담기고, 체인의 나머지는 쳐다보지도 않고 끝납니다.else: — 위의 모든 관문에서 거짓이었던 경우, 즉 -1.0 이하만 도달하는 자리입니다.print(f"...") — 블록 안에서 만든 변수 phase를 바깥에서 출력합니다. 네 갈래 중 어느 길로 갔든 phase에는 반드시 무언가 담겨 있으므로 안전합니다.elif 체인의 핵심은 위에서부터 차례로 검사하다가 처음 참이 되는 곳에서 멈춘다는 것입니다. 이 성질 덕분에 코드가 짧아지지만, 대신 조건을 놓는 순서가 곧 논리가 됩니다. 순서를 잘못 놓으면 무슨 일이 생기는지는 잠시 뒤 실수 노트에서 직접 확인하겠습니다.
방금 본 것처럼 elif는 앞 조건의 부정을 암묵적으로 물려받지만, 구간 하나를 단독으로 검사하고 싶을 때도 있습니다. 한국은행의 물가안정목표는 2%입니다. 물가상승률이 목표 부근, 이를테면 1% 이상 3% 미만에 있는지 묻고 싶다면 수학 시간에 쓰던 표기를 파이썬에 그대로 쓸 수 있습니다.
inflation = 2.4 # 소비자물가 상승률(%)
if 1.0 <= inflation < 3.0:
print(f"물가상승률 {inflation}%: 물가안정목표(2%) 부근의 안정 구간입니다.")
else:
print(f"물가상승률 {inflation}%: 목표 구간을 벗어났습니다.")물가상승률 2.4%: 물가안정목표(2%) 부근의 안정 구간입니다.
1.0 <= inflation < 3.0은 1.0 <= inflation and inflation < 3.0을 줄인 것으로, 파이썬이 공식적으로 지원하는 연쇄 비교입니다. \(1.0 \le x < 3.0\)라는 수학 표기가 거의 그대로 코드가 되는 셈이라, 경제학 교과서의 구간 조건을 옮길 때 특히 요긴합니다. 모든 언어가 이 표기를 지원하는 것은 아니니, 파이썬의 작은 사치라고 생각해도 좋습니다.
실수 노트: elif의 순서 — 에러 없이 틀리는 코드
IndentationError나 SyntaxError는 시끄럽게 항의라도 해 줍니다. 정말 무서운 것은 조용히 틀리는 코드입니다. 아까의 경기 국면 분류에서 조건의 순서만 바꿔 보겠습니다.
growth_rate = 4.5 # 명백한 고성장인데
if growth_rate >= 1.0:
phase = "중성장"
elif growth_rate >= 3.0:
phase = "고성장"
else:
phase = "저성장 또는 후퇴"
print(f"성장률 {growth_rate}% → '{phase}' 국면")성장률 4.5% → '중성장' 국면
4.5%는 누가 봐도 고성장인데 결과는 “중성장”입니다. 에러 메시지는 한 줄도 없습니다. 이유는 elif 체인이 처음 참이 되는 곳에서 멈추기 때문입니다. 4.5는 첫 조건 >= 1.0부터 참이므로, 더 엄격한 >= 3.0은 검사할 기회조차 얻지 못합니다. 넓은 조건이 위에 있으면 아래의 좁은 조건은 영원히 도달 불가능한 코드가 됩니다.
>= 방향으로 내려가는 체인이라면 큰 기준부터, <= 방향이라면 작은 기준부터. 구간 분류를 쓸 때마다 경계 값 몇 개(딱 3.0, 살짝 아래 2.9, 살짝 위 3.1)를 넣어 눈으로 확인하는 습관을 들이면 이런 조용한 버그를 잡을 수 있습니다.
순서 감각을 익혔으니 elif 체인을 하나 더 연습해 보겠습니다. 이번에는 기업 분석에서 흔히 쓰는 지표입니다. 부채비율은 자기자본 대비 부채의 비율로, 통상 100% 미만이면 안정적이라고 이야기합니다. 아래 기업과 판정 기준은 수업을 위해 만든 가상의 시나리오입니다.
debt_ratio = 185.2 # 가상 기업 '두루상사'의 부채비율(%)
if debt_ratio < 100.0:
grade = "안정"
elif debt_ratio < 200.0:
grade = "주의"
else:
grade = "위험"
print(f"부채비율 {debt_ratio}% → 재무 안정성 '{grade}' 단계 (학습용 기준)")부채비율 185.2% → 재무 안정성 '주의' 단계 (학습용 기준)
이번에는 < 방향이므로 작은 기준(100.0)부터 검사한다는 점을 확인해 두시기 바랍니다. 방금 배운 순서 규칙이 방향에 따라 뒤집히는 좋은 예입니다.
# TODO: gpa = 3.7 로 변수를 만든 뒤 elif 체인으로 장학 구간을 판정해 보세요.
# 4.0 이상 → "성적 장학 A", 3.5 이상 → "성적 장학 B", 그 미만 → "다음 학기에 도전"
# 판정 결과를 f-string으로 출력하고, 조건의 순서를 일부러 뒤집으면
# 어떤 gpa 값에서 결과가 틀려지는지도 실험해 보세요.지금까지의 조건은 전부 하나짜리였습니다. 그런데 경제적 판단은 여러 조건이 겹칠 때가 더 많습니다. “물가도 안정적이고 고용도 탄탄한가”, “성장이 꺾였거나 실업이 치솟았는가”. 우리말의 “그리고”와 “또는”에 해당하는 것이 논리 연산자 and와 or입니다.
| 연산자 | 뜻 | True가 되는 경우 |
|---|---|---|
A and B |
그리고 | A, B가 모두 True일 때만 |
A or B |
또는 | A, B 중 하나라도 True이면 |
not A |
부정 | A가 False일 때 |
거시경제 지표 두 개를 함께 보는 판단부터 시작하겠습니다.
inflation = 1.8 # 물가상승률(%)
unemployment = 3.5 # 실업률(%)
if inflation < 2.0 and unemployment < 4.0:
print("물가와 고용이 모두 안정적입니다.")
else:
print("두 지표 중 적어도 하나는 기준을 벗어났습니다.")물가와 고용이 모두 안정적입니다.
and는 까다로운 접속사입니다. 물가 조건이 참이어도 실업률이 4.5%였다면 전체는 거짓이 되어 else로 갑니다. 반대로 or는 너그러운 접속사여서, 여러 경고 신호 중 하나만 켜져도 반응해야 하는 상황에 어울립니다. 경기 침체의 조짐을 살피는 코드라면 이렇게 됩니다.
growth_rate = 0.3 # 성장률(%)
unemployment = 5.2 # 실업률(%)
if growth_rate < 0 or unemployment > 5.0:
print("경기 경고: 성장 둔화 또는 고용 부진 신호가 있습니다.")
else:
print("뚜렷한 경고 신호는 없습니다.")
is_holiday = False
if not is_holiday:
print("오늘은 휴일이 아니므로 이콘 카페가 정상 영업합니다.")경기 경고: 성장 둔화 또는 고용 부진 신호가 있습니다.
오늘은 휴일이 아니므로 이콘 카페가 정상 영업합니다.
성장률 0.3%는 아직 양수라 첫 조건은 거짓이지만, 실업률이 5%를 넘겨 두 번째 조건이 참이므로 경고가 출력됩니다. 마지막의 not은 불리언 값을 뒤집습니다. is_holiday가 False이니 not is_holiday는 True가 됩니다.
조건이 세 개 이상으로 늘어나면 한 줄에 다 쓰는 대신, 각 조건을 이름 있는 변수에 담는 방법이 있습니다. 기업의 재무 건전성을 세 가지 잣대로 종합 평가해 보겠습니다. 역시 학습용 가상 시나리오입니다.
# 가상 기업 '한빛식품'의 재무 지표 (학습용 가상 시나리오)
current_ratio = 150.5 # 유동비율(%): 단기 부채를 갚을 능력, 100% 이상이면 양호
debt_ratio = 95.8 # 부채비율(%): 낮을수록 부담이 적음
operating_margin = 12.3 # 영업이익률(%): 본업의 수익성
is_liquid = current_ratio >= 100.0
is_solid = debt_ratio < 150.0
is_profitable = operating_margin >= 10.0
print(f"단기 지급능력 통과: {is_liquid}")
print(f"부채 부담 통과: {is_solid}")
print(f"수익성 통과: {is_profitable}")
if is_liquid and is_solid and is_profitable:
print("종합 판정: 세 기준을 모두 통과했습니다.")
else:
print("종합 판정: 통과하지 못한 기준이 있습니다.")단기 지급능력 통과: True
부채 부담 통과: True
수익성 통과: True
종합 판정: 세 기준을 모두 통과했습니다.
is_liquid = current_ratio >= 100.0 같은 줄이 처음에는 낯설 수 있습니다. 비교의 결과인 True/False도 값이므로 변수에 담을 수 있다는 점을 이용한 것입니다. 이렇게 조건마다 이름을 붙여 두면 if 줄이 is_liquid and is_solid and is_profitable처럼 거의 문장으로 읽히고, 중간 결과를 출력해서 어느 기준에서 걸렸는지 추적하기도 쉬워집니다. 조건이 복잡해질수록 값어치가 커지는 습관입니다.
한 가지 분명히 해 둘 것이 있습니다. 위 판정 기준은 조건문 연습을 위해 단순화한 것일 뿐, 실제 기업 평가는 업종·시점·회계 기준에 따라 훨씬 정교하게 이루어집니다. 이 수업의 어떤 코드도 실제 투자 판단의 근거가 아니라는 점을 기억해 주시기 바랍니다.
# TODO: 편의점 아르바이트의 주휴수당 자격을 판정해 보세요.
# weekly_hours = 16 (일주일 근무시간), perfect_attendance = True (개근 여부) 변수를 만들고,
# "주 15시간 이상 근무"와 "개근" 두 조건을 모두 만족하면 "주휴수당 대상",
# 아니면 "주휴수당 미대상"을 출력합니다. and를 사용하세요.if 블록 안에 또 if를 넣을 수도 있습니다. 이를 중첩(nested) 조건문이라고 합니다. 이콘 카페가 멤버십 회원에게만 할인을 주되, 회원 중에서도 구매액에 따라 할인율을 달리 준다고 해 보겠습니다.
is_member = True
purchase = 12_000 # 구매액(원). 숫자 사이의 밑줄(_)은 파이썬이 무시하는 자릿수 구분 기호입니다.
if is_member:
if purchase >= 10_000:
discount_rate = 0.10
else:
discount_rate = 0.05
else:
discount_rate = 0.0
payment = purchase * (1 - discount_rate)
print(f"할인율 {discount_rate * 100:.0f}%, 결제 금액 {payment:,.0f}원")할인율 10%, 결제 금액 10,800원
바깥 if는 회원 여부를, 안쪽 if는 구매액을 검사합니다. 안쪽 블록은 들여쓰기가 여덟 칸이 된다는 점에 주목하시기 바랍니다. 블록 속의 블록이므로 한 단계 더 들어가는 것입니다. 출력에 쓴 {payment:,.0f}는 2장에서 본 f-string 형식 지정으로, 쉼표는 천 단위 구분, .0f는 소수점 없이 표시하라는 뜻입니다. 앞으로 돈 계산 출력에 계속 쓰게 됩니다.
그런데 같은 논리를 중첩 없이 쓸 수도 있습니다. and와 elif를 조합하면 됩니다.
if is_member and purchase >= 10_000:
discount_rate = 0.10
elif is_member:
discount_rate = 0.05
else:
discount_rate = 0.0
print(f"할인율 {discount_rate * 100:.0f}% (중첩 없이 같은 결과)")할인율 10% (중첩 없이 같은 결과)
어느 쪽이 좋은가는 상황에 따라 다릅니다. 중첩은 “회원인가?”라는 큰 질문 아래 세부 질문이 매달린 구조를 그대로 보여 주고, 평평한 버전은 갈래의 전체 목록이 한눈에 들어옵니다. 다만 중첩이 세 겹, 네 겹으로 깊어지면 읽기가 급격히 어려워지므로, 두 겹을 넘어갈 것 같으면 조건을 다시 정리하라는 신호로 받아들이는 편이 좋습니다.
조건식에 쓸 수 있는 연산자를 하나만 더 소개하겠습니다. in은 “왼쪽이 오른쪽 안에 들어 있는가”를 묻습니다. 문자열에 쓰면 부분 문자열 검사가 됩니다.
order = "아이스 아메리카노 (큰 컵)"
if "아메리카노" in order:
print("아메리카노 계열 주문입니다. 원두 두 샷을 준비합니다.")
if "디카페인" not in order:
print("일반 원두로 내립니다.")아메리카노 계열 주문입니다. 원두 두 샷을 준비합니다.
일반 원두로 내립니다.
주문 문자열 어딘가에 “아메리카노”가 포함되어 있으면 참이고, not in은 그 반대입니다. 지금은 문자열 안을 뒤지는 정도지만, in의 진짜 무대는 다음 장입니다. 4장에서 리스트를 배우면 “이 메뉴가 메뉴판 목록에 있는가”, “이 나라가 분석 대상 목록에 있는가”처럼 여러 값을 담은 상자 전체를 한 번에 검사하게 됩니다.
조건에 따라 변수에 담을 값만 달라지는 간단한 상황이라면, 네 줄짜리 if/else를 한 줄로 줄이는 문법이 있습니다. 이콘 카페의 오늘 손익을 한 단어로 요약해 보겠습니다.
profit = -35_000 # 오늘의 이익(원). 재료비 지출이 많았던 날입니다.
status = "흑자" if profit >= 0 else "적자"
print(f"오늘 이콘 카페의 손익: {profit:,}원 ({status})")오늘 이콘 카페의 손익: -35,000원 (적자)
값1 if 조건 else 값2 어순이 처음에는 어색하지만, “흑자다, 이익이 0 이상이면. 아니면 적자다”라고 읽으면 우리말 어순과 크게 다르지 않습니다. 조건이 참이면 값1, 거짓이면 값2가 통째로 하나의 값이 되어 변수에 담깁니다. 이를 조건부 표현식(conditional expression)이라고 부릅니다.
쓰임새는 분명히 제한적입니다. 갈래마다 실행할 문장이 여러 개이거나 갈래가 셋 이상이면 그냥 if 문을 쓰는 것이 낫습니다. “짧은 이지선다로 값 하나 고르기”가 아니라면 무리해서 한 줄로 줄이지 않는 것, 그것이 이 문법을 잘 쓰는 요령입니다.
이번 장의 문법을 총동원할 무대는 소득세입니다. 아르바이트 소득에도, 첫 월급에도 결국 따라오는 세금이므로 남의 이야기가 아닙니다.
먼저 흔한 오해 하나에서 출발하겠습니다. “연봉이 올라서 세금 구간이 바뀌면 세율이 확 뛰니까, 구간 경계 직전이 오히려 이득이다”라는 말을 들어 본 적이 있을 것입니다. 정말 그럴까요? 감으로 말고, 계산해 보겠습니다.
한국의 소득세는 과세표준(총급여에서 각종 공제를 뺀, 세금을 매기는 기준 금액)의 구간별로 세율이 올라가는 누진 구조입니다. 2024년 기준 세율표는 다음과 같습니다. 이 장에서는 각종 공제·지방소득세를 생략하고 이 표만으로 계산하는 교육용 단순화 버전을 다룬다는 점을 미리 밝혀 둡니다.
| 과세표준 | 세율 | 누진공제 |
|---|---|---|
| 1,400만 원 이하 | 6% | — |
| 1,400만 초과 ~ 5,000만 원 이하 | 15% | 126만 원 |
| 5,000만 초과 ~ 8,800만 원 이하 | 24% | 576만 원 |
| 8,800만 초과 ~ 1억 5,000만 원 이하 | 35% | 1,544만 원 |
| 1억 5,000만 초과 ~ 3억 원 이하 | 38% | 1,994만 원 |
| 3억 초과 ~ 5억 원 이하 | 40% | 2,594만 원 |
| 5억 초과 ~ 10억 원 이하 | 42% | 3,594만 원 |
| 10억 원 초과 | 45% | 6,594만 원 |
누진공제 열은 잠시 뒤에 정체를 밝히기로 하고, 우선 오해의 현장부터 재연하겠습니다. 과세표준이 딱 1,400만 원인 A와, 10만 원 더 많은 B가 있습니다. 만약 “구간이 바뀌면 소득 전체에 새 세율이 붙는다”는 오해가 사실이라면 이런 일이 벌어집니다.
income_a = 14_000_000 # A의 과세표준(원)
income_b = 14_100_000 # B의 과세표준(원): A보다 10만 원 많음
tax_a = income_a * 0.06 # A는 1구간이므로 6%
wrong_tax_b = income_b * 0.15 # 오해: B의 소득 전체에 15%를 적용
print(f"A의 세액: {tax_a:,.0f}원 → 세후 소득 {income_a - tax_a:,.0f}원")
print(f"B의 세액(오해 버전): {wrong_tax_b:,.0f}원 → 세후 소득 {income_b - wrong_tax_b:,.0f}원")A의 세액: 840,000원 → 세후 소득 13,160,000원
B의 세액(오해 버전): 2,115,000원 → 세후 소득 11,985,000원
오해가 사실이라면 B는 A보다 10만 원을 더 벌고도 세후 소득이 100만 원 넘게 적어집니다. 이런 역전이 실제로 일어난다면 아무도 구간 경계를 넘으려 하지 않을 테니, 세제가 그렇게 설계되어 있을 리 없습니다.
실제 누진세는 소득을 구간별로 잘라서 각 구간에 그 구간의 세율만 적용합니다. B의 소득 1,410만 원 중 1,400만 원까지는 여전히 6%로 과세되고, 경계를 넘은 10만 원에만 15%가 붙습니다.
correct_tax_b = 14_000_000 * 0.06 + (income_b - 14_000_000) * 0.15
print(f"B의 세액(올바른 계산): {correct_tax_b:,.0f}원")
print(f"B의 세후 소득: {income_b - correct_tax_b:,.0f}원 (A는 {income_a - tax_a:,.0f}원)")B의 세액(올바른 계산): 855,000원
B의 세후 소득: 13,245,000원 (A는 13,160,000원)
B의 세금은 A보다 15,000원 많을 뿐이고, 세후 소득은 여전히 B가 높습니다. 구간을 넘어도 손해는 없습니다. 늘어난 부분에만 높은 세율이 붙기 때문입니다.
이 “구간별로 잘라 더하기” 논리는 그대로 elif 체인이 됩니다. 우선 앞의 세 구간만으로 계산기를 만들어 보겠습니다. 과세표준 4,200만 원, 사회초년생의 연봉으로 흔한 수준입니다.
income = 42_000_000 # 과세표준(원)
if income <= 14_000_000:
tax = income * 0.06
elif income <= 50_000_000:
tax = 14_000_000 * 0.06 + (income - 14_000_000) * 0.15
elif income <= 88_000_000:
tax = 14_000_000 * 0.06 + 36_000_000 * 0.15 + (income - 50_000_000) * 0.24
print(f"과세표준 {income:,}원의 산출세액: {tax:,.0f}원")과세표준 42,000,000원의 산출세액: 5,040,000원
if income <= 14_000_000: — 1구간. 소득 전체가 첫 구간 안에 있으므로 전부 6%입니다.elif income <= 50_000_000: — 2구간. 여기 도달했다는 것은 소득이 1,400만 원을 넘는다는 뜻입니다. 그래서 세액은 두 조각의 합이 됩니다. 첫 조각 14_000_000 * 0.06은 1구간을 가득 채운 부분의 세금 84만 원이고, 둘째 조각 (income - 14_000_000) * 0.15는 경계를 넘은 부분에만 15%를 매긴 것입니다. 4,200만 원이 여기에 걸려, 840,000 + 28,000,000 × 0.15 = 5,040,000원이 나옵니다.elif income <= 88_000_000: — 3구간. 조각이 세 개로 늘어납니다. 1구간 전체(84만 원), 2구간 전체 36_000_000 * 0.15(1,400만~5,000만 사이의 3,600만 원에 15%, 540만 원), 그리고 5,000만 원을 넘은 부분에 24%.print는 어느 구간이었든 tax에 담긴 결과를 출력합니다. 단, 이 3구간 버전에 8,800만 원 초과 소득을 넣으면 어떤 블록도 실행되지 않아 tax가 만들어지지 않고, print에서 NameError가 납니다. 계산기가 완성되려면 여덟 구간을 모두 채워야 합니다.그런데 구간이 늘수록 “앞 구간 전체 세금”을 더하는 부분이 길어집니다. 8구간을 이 방식으로 쓰면 마지막 줄은 조각 여덟 개의 합이 됩니다. 세율표의 마지막 열, 누진공제가 바로 이 수고를 덜어 주는 장치입니다.
2구간의 세액을 다시 보면,
\[\text{세액} = 840{,}000 + (\text{과세표준} - 14{,}000{,}000) \times 0.15\]
괄호를 풀어 정리하면,
\[\text{세액} = \text{과세표준} \times 0.15 - 1{,}260{,}000\]
이 됩니다. 마지막의 126만 원이 세율표의 “누진공제”입니다. 즉 누진공제란 “소득 전체에 그 구간 세율을 곱한 뒤, 아래 구간들에서 실제보다 더 걷은 만큼 돌려주는 금액”을 미리 계산해 둔 것입니다. 덕분에 어느 구간이든 세액은
\[\text{세액} = \text{과세표준} \times \text{한계세율} - \text{누진공제}\]
라는 한 줄 공식으로 구할 수 있습니다. 이 공식으로 여덟 구간 전체를 갖춘 계산기를 완성하겠습니다. 과세표준 1억 원을 넣어 보겠습니다.
income = 100_000_000 # 과세표준(원)
if income <= 14_000_000:
tax = income * 0.06
elif income <= 50_000_000:
tax = income * 0.15 - 1_260_000
elif income <= 88_000_000:
tax = income * 0.24 - 5_760_000
elif income <= 150_000_000:
tax = income * 0.35 - 15_440_000
elif income <= 300_000_000:
tax = income * 0.38 - 19_940_000
elif income <= 500_000_000:
tax = income * 0.40 - 25_940_000
elif income <= 1_000_000_000:
tax = income * 0.42 - 35_940_000
else:
tax = income * 0.45 - 65_940_000
average_rate = tax / income * 100
print(f"과세표준: {income:,}원")
print(f"산출세액: {tax:,.0f}원")
print(f"평균세율: {average_rate:.2f}%")과세표준: 100,000,000원
산출세액: 19,560,000원
평균세율: 19.56%
출력을 보면 흥미로운 대목이 있습니다. 과세표준 1억 원은 35% 구간에 있는데, 실제로 낸 세금은 소득의 19.56%에 불과합니다. 두 숫자는 서로 다른 질문에 대한 답이기 때문입니다.
한계세율(marginal tax rate)은 “여기서 1원을 더 벌면 그중 얼마를 세금으로 내는가”에 대한 답입니다. 1억 원의 한계세율은 35%입니다. 반면 평균세율(average tax rate)은 “지금까지 번 소득 전체 중 얼마를 세금으로 냈는가”입니다.
\[\text{평균세율} = \frac{\text{산출세액}}{\text{과세표준}}\]
소득의 앞부분이 6%, 15%, 24% 같은 낮은 세율로 과세된 덕분에 평균은 한계보다 항상 낮습니다. 한계세율이 정말 35%인지는 실험으로 확인할 수 있습니다. 소득을 100만 원 늘려서 세금이 얼마나 느는지 보면 됩니다.
extra = 1_000_000
income_more = income + extra # 1억 100만 원: 여전히 8,800만~1.5억 구간이므로 같은 공식 사용
tax_more = income_more * 0.35 - 15_440_000
print(f"소득 {extra:,}원 증가 → 세금 {tax_more - tax:,.0f}원 증가")
print(f"증가분에 적용된 세율: {(tax_more - tax) / extra * 100:.0f}% (= 한계세율)")소득 1,000,000원 증가 → 세금 350,000원 증가
증가분에 적용된 세율: 35% (= 한계세율)
추가된 100만 원 중 정확히 35만 원이 세금으로 나갑니다. 이것이 한계세율의 의미입니다. “구간이 바뀌면 손해”라는 오해는 한계세율(새로 버는 돈에 붙는 세율)을 평균세율(소득 전체에 대한 세 부담)로 잘못 읽은 데서 나온 것임을 이제 코드로 설명할 수 있습니다.
이 계산기는 2장에서 배운 input()과 붙이면 대화형 도구가 됩니다. Colab에서 아래 셀을 직접 실행해 여러 소득을 넣어 보시기 바랍니다.
income = int(input("과세표준을 원 단위로 입력하세요: "))
if income <= 14_000_000:
tax = income * 0.06
elif income <= 50_000_000:
tax = income * 0.15 - 1_260_000
elif income <= 88_000_000:
tax = income * 0.24 - 5_760_000
elif income <= 150_000_000:
tax = income * 0.35 - 15_440_000
elif income <= 300_000_000:
tax = income * 0.38 - 19_940_000
elif income <= 500_000_000:
tax = income * 0.40 - 25_940_000
elif income <= 1_000_000_000:
tax = income * 0.42 - 35_940_000
else:
tax = income * 0.45 - 65_940_000
print(f"산출세액: {tax:,.0f}원, 평균세율: {tax / income * 100:.2f}%")실행 예시는 다음과 같습니다.
과세표준을 원 단위로 입력하세요: 66000000
산출세액: 10,080,000원, 평균세율: 15.27%
# TODO: income = 50_000_000 (과세표준 5,000만 원)의 세액을 두 방식으로 계산해 보세요.
# 방식 1 (구간별 합산): 14_000_000 * 0.06 + 36_000_000 * 0.15
# 방식 2 (누진공제): income * 0.15 - 1_260_000
# 두 결과를 각각 변수에 담아 출력하고, == 비교로 같은지 확인합니다.두 번째 응용은 정부(또는 총학생회)가 가격에 직접 개입하는 상황입니다. 경제학원론은 두 가지 개입을 구분합니다. 가격상한제는 “이 값보다 비싸게 팔지 마라”(임대료 규제가 고전적인 예), 가격하한제는 “이 값보다 싸게 사지 마라”(최저임금이 대표적인 예)입니다.
핵심 질문은 하나입니다. 그 상한선 또는 하한선이 실제로 시장을 움직이는가, 즉 구속력(binding)이 있는가. 이 판정이야말로 조건문의 일입니다.
이콘 카페 사례로 시작하겠습니다. 총학생회가 “교내 커피가 너무 비싸다”며 아메리카노 상한가를 2,000원으로 정하라고 요구한다고 해 봅시다. 교내 커피 시장의 하루 수요량과 공급량이 가격 \(P\)에 따라 다음처럼 움직인다고 가정합니다(교육용 가상 숫자입니다).
\[Q_d = 700 - 0.2P, \qquad Q_s = -300 + 0.2P\]
두 식을 같다고 놓으면 균형가격은 2,500원, 균형거래량은 하루 200잔입니다. 상한가 2,000원은 균형가격보다 낮으므로 시장은 균형으로 돌아가지 못합니다. 그 결과를 조건문이 판정하고, 조건이 참일 때만 초과수요까지 계산하게 만들겠습니다.
equilibrium_price = 2500 # 균형가격(원)
price_ceiling = 2000 # 총학생회가 요구한 상한가(원)
if price_ceiling < equilibrium_price:
quantity_demanded = 700 - 0.2 * price_ceiling
quantity_supplied = -300 + 0.2 * price_ceiling
shortage = quantity_demanded - quantity_supplied
print("상한가가 균형가격보다 낮습니다 → 구속력 있는 가격상한")
print(f"상한가 {price_ceiling:,}원에서 수요량 {quantity_demanded:.0f}잔, 공급량 {quantity_supplied:.0f}잔")
print(f"초과수요 {shortage:.0f}잔: 줄서기, 품절, 끼워팔기 같은 비가격 배분이 나타납니다.")
else:
print("상한가가 균형가격 이상입니다 → 구속력 없음, 시장은 균형가격으로 거래합니다.")상한가가 균형가격보다 낮습니다 → 구속력 있는 가격상한
상한가 2,000원에서 수요량 300잔, 공급량 100잔
초과수요 200잔: 줄서기, 품절, 끼워팔기 같은 비가격 배분이 나타납니다.
수량 계산이 if 블록 안에 들어 있다는 점이 이 코드의 요점입니다. 상한이 구속력이 없다면 초과수요라는 개념 자체가 성립하지 않으므로, 계산할 필요가 있을 때만 계산합니다. price_ceiling을 3,000원으로 바꿔 다시 실행해 보면 else 갈래가 확인해 줍니다. 균형가격보다 높은 곳에 그은 상한선은 아무도 건드리지 않는 선일 뿐입니다.
이제 방향을 뒤집어 가격하한을 보겠습니다. 2025년 법정 최저시급은 10,030원입니다. 어느 대학가 아르바이트 시장의 시간당 노동 수요와 공급이 시급 \(w\)에 대해 다음과 같고(역시 교육용 가상 숫자), 균형시급이 9,500원이라고 합시다.
\[L_d = 1500 - 0.1w, \qquad L_s = -400 + 0.1w\]
하한이 구속력을 갖는 조건은 상한과 반대입니다. 최저임금이 균형시급보다 높아야 시장을 움직입니다.
min_wage = 10_030 # 2025년 법정 최저시급(원)
equilibrium_wage = 9_500 # 이 동네 아르바이트 시장의 균형시급(원, 가상)
if min_wage > equilibrium_wage:
labor_demanded = 1500 - 0.1 * min_wage
labor_supplied = -400 + 0.1 * min_wage
surplus = labor_supplied - labor_demanded
print("최저임금이 균형시급보다 높습니다 → 구속력 있는 가격하한")
print(f"시급 {min_wage:,}원에서 채용하려는 자리 {labor_demanded:.0f}개, 일하려는 사람 {labor_supplied:.0f}명")
print(f"노동 초과공급 {surplus:.0f}명: 더 받게 된 사람과 자리를 못 구한 사람이 함께 생깁니다.")
else:
print("최저임금이 균형시급 이하입니다 → 구속력 없음, 시장 시급이 그대로 적용됩니다.")최저임금이 균형시급보다 높습니다 → 구속력 있는 가격하한
시급 10,030원에서 채용하려는 자리 497개, 일하려는 사람 603명
노동 초과공급 106명: 더 받게 된 사람과 자리를 못 구한 사람이 함께 생깁니다.
두 코드를 나란히 놓고 보면 대칭이 뚜렷합니다. 상한은 균형보다 낮아야(<) 힘을 갖고, 하한은 균형보다 높아야(>) 힘을 갖습니다. “상한인데 낮아야 묶인다”는 부분에서 처음에는 다들 한 번씩 헷갈리는데, 부등호의 방향을 조건문으로 직접 써 보면 혼동이 줄어듭니다. 조건식이 곧 이론의 요약인 셈입니다.
덧붙여 두자면, 위 모형은 완전경쟁 노동시장을 가정한 교과서의 첫 그림입니다. 실제 최저임금의 고용 효과는 시장 구조(예: 수요독점)에 따라 달라질 수 있어 경제학에서 오래 논쟁 중인 주제입니다. 단순한 모형의 결론을 현실에 그대로 얹지 않는 신중함도 이 수업에서 함께 연습해야 할 태도입니다.
1. 도시락을 살 수 있을까 — 변수 lunch_money = 6000(점심 예산), dosirak = 5800(편의점 도시락 가격)을 만들고, 예산이 가격 이상이면 남는 돈을, 부족하면 모자란 금액을 각각 f-string으로 출력하는 if/else 코드를 작성하세요.
2. 성장 국면 판정 — 변수 growth = -0.4(성장률, %)에 대해 양수면 “성장”, 정확히 0이면 “제자리”, 음수면 “후퇴”를 출력하세요. elif와 ==를 사용하고, 세 갈래가 모두 작동하는지 값을 바꿔 확인하세요.
3. 물가안정목표 구간 — 변수 inflation = 2.4(물가상승률, %)가 1.0 이상 3.0 미만이면 “안정 구간”, 1.0 미만이면 “저물가”, 그 외에는 “고물가”를 출력하세요. 첫 조건은 반드시 연쇄 비교(1.0 <= inflation < 3.0)로 쓰세요.
4. 스태그플레이션 경보 — 변수 inflation = 5.1, growth = 0.4를 만들고, 물가상승률이 4%를 넘으면서 성장률이 1% 미만이면 “스태그플레이션 우려”를, 아니면 “우려 단계 아님”을 출력하세요. and를 사용하고, 두 지표 값을 f-string으로 함께 출력하세요.
5. 원두 재주문 판정 — 이콘 카페의 재고 관리입니다. 변수 stock_kg = 4.2(원두 재고), has_event = True(다음 주 행사 여부)를 만들고, 재고가 5kg 미만이거나 행사가 예정되어 있으면 “재주문 필요”를, 둘 다 아니면 “재고 충분”을 출력하세요. or를 사용하세요.
6. 가격상한 삼중 판정 — 변수 price_ceiling과 equilibrium_price를 만들고, 상한이 균형가격보다 낮으면 “구속력 있음: 초과수요 발생”, 높으면 “구속력 없음”, 정확히 같으면 “경계 사례: 시장가격과 일치”를 출력하는 elif 체인을 작성하세요. 세 경우가 모두 나오도록 값을 바꿔 가며 세 번 실행해 보세요.
7. 평균세율 계산기 — 과세표준 66,000,000원의 산출세액을 3.8절의 8구간 누진공제 방식으로 계산하고, 평균세율(%)을 소수 둘째 자리까지 출력하세요. 이 소득의 한계세율은 24%입니다. 평균세율이 그보다 낮게 나오는 이유를 코드 아래에 주석 한두 문장으로 설명하세요.
8. 구간 경계 실험 — 과세표준 88,000,000원(24% 구간의 끝)과 89,000,000원(35% 구간의 시작)의 산출세액과 세후 소득을 각각 계산해 출력하세요. 구간이 바뀌었는데도 세후 소득이 역전되지 않음을 출력으로 확인하고, 그 이유를 주석 두 문장으로 서술하세요.
풀이는 부록 C에 있습니다.
과제: 나의 소득세 리포트 (예상 소요 30~60분)
여러분의 커리어를 세 장면으로 상상해 봅시다. 실제 연봉이 아니라 과세표준 기준의 교육용 가정입니다.
요구사항
elif 체인으로 각 장면의 산출세액을 계산하세요. 아직 반복문을 배우지 않았으므로, 변수 값을 바꿔 세 번 실행하거나 코드 블록을 세 벌 쓰면 됩니다.3문단 글쓰기 틀 — 표 아래에 마크다운 셀로 작성합니다.
자기 점검 체크리스트
이번 장에서 프로그램은 처음으로 스스로 길을 골랐습니다. if는 조건이 참일 때만 블록을 실행하고, else는 나머지 모든 경우를 받아내며, elif는 여러 구간을 위에서부터 차례로 맡되 처음 참이 되는 곳에서 멈춥니다. 조건의 재료는 비교 연산자가 만들어 내는 True와 False이고, and·or·not이 여러 판단을 하나로 묶어 줍니다. 들여쓰기가 장식이 아니라 문법이라는 점, =와 ==가 전혀 다른 기호라는 점, 그리고 elif의 순서가 뒤바뀌면 에러 없이 조용히 틀린다는 점은 앞으로도 여러분의 발목을 잡을 수 있으니 실수 노트를 한 번 더 읽어 둘 가치가 있습니다. 경제학 쪽의 수확도 분명합니다. 한계편익과 가격의 비교, 소득세의 구간별 과세, 가격상한·하한의 구속력 판정이 모두 “조건에 따른 선택”이라는 같은 뼈대 위에 서 있음을 확인했고, 특히 한계세율과 평균세율의 구분은 세금 관련 뉴스나 대화에서 바로 써먹을 수 있는 이해입니다.
한 가지 아쉬움도 남았을 것입니다. 소득세 계산기에 새 소득을 넣으려면 매번 변수 값을 고쳐 다시 실행해야 했습니다. 소득이 100개라면 100번 반복해야 할까요? 다음 장에서 리스트에 여러 값을 담고 for 반복문으로 한 번에 처리하는 방법을 배우면 이 문제가 풀립니다. 오늘 문자열에만 써 본 in 연산자도 리스트를 만나 제 역할을 찾고, 여러 해의 성장률을 계산한 결과를 이 책의 첫 그래프로 그리게 됩니다.