조건문과 반복문의 차이: 선택과 반복으로 이해하는 제어 구조

조건문과 반복문이란? Python으로 프로그램의 실행 흐름 제어하기#

변수는 값을 기억합니다. 하지만 값을 저장하는 것만으로 프로그램이 완성되지는 않습니다. 저장한 값을 살펴보고 어떤 작업을 할지 선택하거나, 여러 값에 대해 같은 작업을 반복해야 합니다.

이때 사용하는 문법이 제어 구조입니다. 프로그램의 실행 흐름을 바꾸는 기본적인 방법은 다음 두 가지입니다.

제어 구조 하는 일 대표적인 Python 문법
조건문 조건에 따라 실행할 코드를 선택한다 if, elif, else
반복문 조건이나 데이터의 개수에 따라 코드를 여러 번 실행한다 for, while

예를 들어 쇼핑몰에서 사용자의 주문 금액이 5만 원 이상일 때만 무료배송을 적용한다면 조건문이 필요합니다. 장바구니에 담긴 모든 상품의 가격을 더한다면 반복문이 필요합니다.

두 문법을 함께 사용하면 “장바구니의 상품을 하나씩 살펴보고, 할인 대상인 상품만 합산한다”와 같은 실제 업무 흐름도 코드로 표현할 수 있습니다.

실행 흐름을 제어한다는 것은 무슨 뜻일까?#

별도의 제어 구조가 없다면 Python은 일반적으로 코드를 위에서 아래로 실행합니다.

price = 10_000
quantity = 3

total = price * quantity
print(total)  # 30000

하지만 모든 사용자의 주문이 같은 상황은 아닙니다. 배송비 적용 여부는 주문 금액에 따라 달라지고, 상품 개수도 매번 달라집니다. 프로그램이 입력과 상태에 맞춰 동작하려면 실행 경로를 선택하고 반복 횟수를 결정할 수 있어야 합니다.

핵심: 조건문은 “이번에는 어느 코드를 실행할까?”를 결정하고, 반복문은 “이 코드를 언제까지 실행할까?”를 결정합니다.

조건문: 조건에 따라 실행할 코드 선택하기#

조건문은 조건을 평가한 뒤 결과에 따라 실행 경로를 고르는 문법입니다. Python에서는 주로 if, elif, else를 사용합니다.

조건에는 True 또는 False로 판단할 수 있는 표현식을 넣습니다.

order_total = 60_000

print(order_total >= 50_000)  # True

>=는 왼쪽 값이 오른쪽 값보다 크거나 같은지 비교합니다. 이 비교 결과가 조건문의 실행 여부를 결정합니다.

if: 조건이 참일 때 실행하기#

order_total = 60_000

if order_total >= 50_000:
    print("무료배송 대상입니다.")

print("주문 금액 확인이 끝났습니다.")

실행 결과:

무료배송 대상입니다.
주문 금액 확인이 끝났습니다.

Python은 order_total >= 50_000을 평가합니다. 값이 True이므로 들여쓰기 된 print()를 실행합니다. 그다음에는 if 블록 밖에 있는 마지막 줄을 실행합니다.

주문 금액을 30_000으로 바꾸면 조건이 False가 되어 무료배송 안내는 건너뜁니다. 마지막 줄은 조건과 무관하게 실행됩니다.

주문 금액 확인이 끝났습니다.

즉, 조건문 밖에 있는 코드는 조건문의 실행 여부와 별개로 다음 순서에 실행됩니다.

Python에서 들여쓰기는 문법이다#

Python은 중괄호 대신 들여쓰기로 코드의 소속을 구분합니다.

order_total = 60_000

if order_total >= 50_000:
    print("무료배송 대상입니다.")
    print("배송비는 0원입니다.")

print("주문을 계속 진행합니다.")

무료배송 조건이 참일 때만 앞의 두 줄이 실행됩니다. 마지막 줄은 if 블록 밖에 있습니다.

같은 블록에 속하는 코드는 들여쓰기 깊이를 맞춰야 합니다. 한 줄의 들여쓰기가 달라지면 문법 오류가 발생하거나 코드의 의미가 바뀔 수 있습니다. Python에서는 일반적으로 공백 4칸을 사용합니다.

else: 조건이 거짓일 때 실행하기#

if만 사용하면 조건이 거짓일 때 아무 안내도 하지 않습니다. 두 경우를 모두 처리하려면 else를 붙입니다.

order_total = 30_000

if order_total >= 50_000:
    print("무료배송 대상입니다.")
else:
    print("배송비가 추가됩니다.")

print("주문 금액 확인이 끝났습니다.")

실행 결과:

배송비가 추가됩니다.
주문 금액 확인이 끝났습니다.

if와 else는 하나의 갈림길입니다. 조건이 참이면 if 블록을, 거짓이면 else 블록을 실행합니다. 한 번의 판단에서 두 블록이 동시에 실행되지는 않습니다.

elif: 선택지가 여러 개일 때 사용하기#

조건이 둘보다 많다면 elif로 선택지를 추가합니다. 학생의 점수에 따라 학점을 계산해 보겠습니다.

score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"점수: {score}, 학점: {grade}")

실행 결과:

점수: 85, 학점: B

Python은 조건을 위에서 아래로 확인합니다.

  1. 85 >= 90은 거짓입니다.
  2. 85 >= 80은 참이므로 grade = "B"를 실행합니다.
  3. 이미 참인 분기를 찾았으므로 아래의 elif와 else는 확인하지 않습니다.

이 예제에서 elif score >= 80은 앞의 score >= 90을 통과하지 못한 경우에만 평가됩니다. 따라서 이 분기에 도달한 점수는 이미 90점 미만입니다.

조건의 순서가 결과를 바꾼다#

아래처럼 넓은 조건을 먼저 쓰면 의도와 다른 결과가 나옵니다.

score = 95

if score >= 60:
    grade = "D"
elif score >= 90:
    grade = "A"

print(grade)  # D

95점도 score >= 60에 해당합니다. 첫 번째 조건이 참이어서 뒤의 90점 조건까지 도달하지 않습니다.

점수 구간처럼 범위가 겹치는 조건은 더 엄격한 조건부터 배치하거나, 각 범위를 명시적으로 표현해야 합니다.

비교 연산자와 논리 연산자#

조건문에서는 값을 비교하거나 여러 조건을 결합하는 일이 많습니다.

연산자 뜻 예시
== 두 값이 같은가 status == "paid"
!= 두 값이 다른가 status != "cancelled"
> 왼쪽이 더 큰가 age > 19
>= 왼쪽이 크거나 같은가 score >= 80
< 왼쪽이 더 작은가 stock < 10
<= 왼쪽이 작거나 같은가 quantity <= 5
and 두 조건이 모두 참인가 is_paid and has_stock
or 둘 중 하나 이상이 참인가 is_admin or is_owner
not 참과 거짓을 뒤집는가 not is_closed

=와 ==는 특히 주의해야 합니다.

status = "paid"       # 변수에 값을 할당
is_paid = status == "paid"  # 두 값이 같은지 비교

print(is_paid)  # True

실제 주문 처리에서는 조건 하나만으로 충분하지 않을 수 있습니다.

is_paid = True
has_stock = False

if is_paid and has_stock:
    print("출고를 진행합니다.")
else:
    print("결제 상태와 재고를 확인합니다.")

결제가 끝났더라도 재고가 없으면 출고하지 않습니다. 조건문은 이렇게 업무 규칙을 코드에 반영하는 지점이 됩니다.

실무에서 확인할 점: 원문의 age > 19는 “20세 이상”이라는 숫자 조건을 설명하는 예제입니다. 실제 성인 인증은 적용 지역의 법령과 기준 시점에 따라 판단해야 하므로, 예제의 비교식을 그대로 서비스 정책에 사용하면 안 됩니다.

반복문: 같은 작업을 필요한 만큼 실행하기#

반복문은 코드 블록을 여러 번 실행합니다. 상품 목록의 모든 상품을 확인하거나, 사용자가 종료를 선택할 때까지 입력을 받는 작업에 쓰입니다.

Python에서 가장 먼저 익힐 반복문은 for와 while입니다.

문법 적합한 상황 반복이 끝나는 시점
for 목록의 각 항목을 처리하거나 정해진 횟수만큼 실행할 때 순회할 항목이 없어졌을 때
while 특정 조건이 유지되는 동안 실행할 때 조건이 거짓이 되었을 때

for: 목록의 각 항목 처리하기#

장바구니에 담긴 상품을 모두 출력해 보겠습니다.

shopping_cart = ["사과", "우유", "계란", "휴지"]

for item in shopping_cart:
    print(f"상품: {item}")

print("상품 목록 출력이 끝났습니다.")

실행 결과:

상품: 사과
상품: 우유
상품: 계란
상품: 휴지
상품 목록 출력이 끝났습니다.

for item in shopping_cart는 장바구니에서 항목을 하나씩 꺼내 item이라는 변수로 사용하라는 뜻입니다. 첫 반복에서는 "사과", 다음 반복에서는 "우유"가 들어갑니다. 모든 항목을 처리하면 반복문이 끝납니다.

상품이 4개에서 100개로 늘어나더라도 출력 코드를 100번 복사할 필요가 없습니다. 목록의 내용이 달라질 뿐 반복문의 구조는 같습니다.

반복하면서 합계 구하기#

반복문은 결과를 누적할 때도 자주 사용합니다.

prices = [3_000, 4_500, 2_000]

total = 0

for price in prices:
    total = total + price

print(f"상품 합계: {total}원")  # 상품 합계: 9500원

반복이 진행될 때 total은 다음처럼 바뀝니다.

처리한 가격 계산 반복 후 total
3,000원 0 + 3000 3,000
4,500원 3000 + 4500 7,500
2,000원 7500 + 2000 9,500

Python에는 숫자 목록의 합계를 구하는 sum(prices)도 있습니다. 여기서는 반복마다 누적 값이 어떻게 바뀌는지 이해하기 위해 for로 직접 작성했습니다.

range(): 정해진 횟수만큼 반복하기#

목록의 항목이 아니라 반복 횟수가 중요하다면 range()를 사용할 수 있습니다.

for number in range(5):
    print(number)

실행 결과:

0
1
2
3
4

range(5)는 0부터 시작해 5는 포함하지 않는 값을 차례로 제공합니다. 따라서 총 5번 반복합니다.

사람에게 보여줄 순번을 1부터 시작하고 싶다면 다음처럼 작성할 수 있습니다.

for count in range(1, 6):
    print(f"{count}번째 안내입니다.")

실행 결과:

1번째 안내입니다.
2번째 안내입니다.
3번째 안내입니다.
4번째 안내입니다.
5번째 안내입니다.

range(1, 6)은 1부터 5까지의 값을 제공합니다. 끝값 6은 포함되지 않습니다. 반복 횟수와 화면에 표시할 번호를 구분해 생각하면 실수를 줄일 수 있습니다.

while: 조건이 참인 동안 반복하기#

while은 매 반복을 시작하기 전에 조건을 확인합니다. 조건이 참이면 블록을 실행하고, 다시 조건을 확인합니다.

number = 1

while number <= 100:
    print(f"현재 숫자: {number}")
    number = number * 2

print(f"반복 종료 후 숫자: {number}")

실행 흐름은 다음과 같습니다.

반복 시작 시 number number <= 100 반복 후 number
1 참 2
2 참 4
4 참 8
8 참 16
16 참 32
32 참 64
64 참 128
128 거짓 반복 종료

마지막 반복에서 64를 출력하고 두 배인 128을 저장합니다. 다음 조건 검사에서 128 <= 100이 거짓이므로 반복문 밖으로 나옵니다.

if는 조건을 확인해 블록을 실행할지 결정하고 지나갑니다. while은 블록을 실행한 뒤 조건 검사로 돌아옵니다. 두 문법의 차이는 여기에 있습니다.

사용자 입력을 기다리는 예시#

반복 횟수를 미리 알 수 없는 상황에서도 while이 유용합니다.

command = ""

while command != "종료":
    command = input("명령을 입력하세요('종료' 입력 시 끝): ")

    if command != "종료":
        print(f"입력한 명령: {command}")

print("프로그램을 종료합니다.")

사용자가 언제 "종료"를 입력할지는 알 수 없습니다. 프로그램은 매번 입력을 받은 다음 조건을 다시 확인합니다.

조건문과 반복문을 함께 사용하기#

실제 프로그램에서는 목록을 순회하면서 각 항목에 조건을 적용하는 일이 많습니다. 주문 상품 중 할인 대상인 상품만 합산해 보겠습니다.

products = [
    {"name": "사과", "price": 3_000, "discounted": True},
    {"name": "우유", "price": 2_500, "discounted": False},
    {"name": "계란", "price": 6_000, "discounted": True},
]

discounted_total = 0

for product in products:
    if product["discounted"]:
        discounted_total += product["price"]
        print(f"합산: {product['name']}")

print(f"할인 대상 상품의 가격 합계: {discounted_total}원")

실행 결과:

합산: 사과
합산: 계란
할인 대상 상품의 가격 합계: 9000원

여기서는 for가 상품을 하나씩 가져오고, if가 그 상품을 합산할지 결정합니다. product["discounted"]에는 True 또는 False가 저장되어 있으므로 조건으로 바로 사용할 수 있습니다.

상품 한 개를 처리할 때마다 조건을 다시 검사한다는 점이 중요합니다. "사과"에서는 참, "우유"에서는 거짓, "계란"에서는 다시 참이 됩니다.

break와 continue: 반복 흐름을 더 세밀하게 제어하기#

반복문 안에서도 상황에 따라 실행 흐름을 바꿀 수 있습니다.

  • break: 반복문 전체를 즉시 끝냅니다.
  • continue: 현재 차례의 남은 코드를 건너뛰고 다음 차례로 넘어갑니다.

예를 들어 상품 목록에서 처음 발견한 품절 상품의 이름만 확인하려면 break를 쓸 수 있습니다.

products = [
    {"name": "사과", "sold_out": False},
    {"name": "우유", "sold_out": True},
    {"name": "계란", "sold_out": True},
]

for product in products:
    if product["sold_out"]:
        print(f"첫 번째 품절 상품: {product['name']}")
        break

반면 품절 상품만 건너뛰고 판매 가능한 상품을 모두 출력하려면 continue가 적합합니다.

for product in products:
    if product["sold_out"]:
        continue

    print(f"구매 가능: {product['name']}")

break와 continue가 없다면 코드를 작성할 수 없는 것은 아닙니다. 다만 중단이나 건너뛰기의 의도가 분명할 때 사용하면 흐름을 읽기 쉬워집니다.

처음 배울 때 자주 하는 실수#

while의 종료 조건을 바꾸지 않아 무한히 반복하기#

number = 1

while number <= 100:
    print(number)
    # number가 바뀌지 않으므로 조건이 계속 참이다.

이 코드는 number가 계속 1이므로 끝나지 않습니다. 반복 안에서 조건에 영향을 주는 값이 어떻게 변하는지 확인해야 합니다.

number = 1

while number <= 100:
    print(number)
    number *= 2

다만 모든 while문이 반드시 숫자를 증가시켜야 하는 것은 아닙니다. 사용자 입력, 파일 읽기 결과, 외부 작업 상태처럼 다음 반복에서 조건을 바꿀 수 있는 사건이 있다면 그에 맞춰 종료를 설계합니다.

조건을 너무 넓게 먼저 작성하기#

score = 95

if score >= 60:
    print("통과")
elif score >= 90:
    print("우수")

95점에는 두 조건이 모두 해당하지만, 첫 번째 분기에서 이미 처리되므로 "우수"는 출력되지 않습니다. 각 분기의 우선순위를 먼저 정하고 조건의 순서를 배치해야 합니다.

리스트 길이와 마지막 인덱스를 혼동하기#

items = ["사과", "우유", "계란"]

for index in range(len(items)):
    print(items[index])

len(items)는 3이고, range(3)은 0, 1, 2를 제공합니다. 마지막 인덱스가 2인 리스트에서 3번 인덱스에 접근하지 않도록 하는 구조입니다.

인덱스가 필요 없다면 더 간단하게 작성할 수 있습니다.

for item in items:
    print(item)

순번과 항목이 모두 필요할 때는 enumerate()를 사용할 수 있습니다.

for index, item in enumerate(items, start=1):
    print(f"{index}번째 상품: {item}")

모든 실패를 else 하나로 묶어 원인을 숨기기#

조건문의 문법이 맞더라도 안내가 모호하면 프로그램을 쓰기 어렵습니다.

is_paid = True
has_stock = False

if is_paid and has_stock:
    print("출고 가능")
else:
    print("출고 불가")

"출고 불가"만으로는 결제와 재고 중 무엇이 문제인지 알 수 없습니다. 이유별 안내가 필요하다면 조건을 나눕니다.

if not is_paid:
    print("결제를 확인해 주세요.")
elif not has_stock:
    print("상품 재고가 없습니다.")
else:
    print("출고할 수 있습니다.")

조건문을 설계할 때는 참일 때 무엇을 할지뿐 아니라 거짓일 때 사용자가 무엇을 알아야 하는지도 함께 생각해야 합니다.

어떤 문법을 선택해야 할까?#

다음 질문으로 시작하면 선택하기 쉽습니다.

  1. 상황에 따라 하나의 실행 경로를 선택해야 하는가? → if·elif·else
  2. 목록의 각 항목을 처리해야 하는가? → for
  3. 횟수를 정해 반복해야 하는가? → for와 range()
  4. 조건이 충족될 때까지 계속해야 하는가? → while
  5. 반복 중 발견한 조건에 따라 중단하거나 건너뛰어야 하는가? → 필요한 경우 break·continue

예를 들어 “상품 목록에서 재고가 있는 상품만 출력한다”는 문제는 목록을 순회해야 하므로 for를 쓰고, 상품마다 재고를 판단해야 하므로 그 안에 if를 넣습니다. 문법을 따로 암기하기보다 문제가 요구하는 흐름을 먼저 말로 써보는 것이 도움이 됩니다.

직접 확인해 보기#

다음 코드를 실행하기 전에 출력 결과를 먼저 예상해 보세요.

scores = [95, 72, 48, 81]
passed_count = 0

for score in scores:
    if score >= 60:
        passed_count += 1
        print(f"{score}점: 통과")
    else:
        print(f"{score}점: 재학습")

print(f"통과한 사람: {passed_count}명")

확인할 질문은 세 가지입니다.

  • for 블록은 몇 번 실행되는가?
  • passed_count는 어느 점수에서 증가하는가?
  • 마지막에 출력되는 통과 인원은 몇 명인가?

정답은 for 블록이 4번 실행되고, 95점·72점·81점에서 인원이 증가하여 최종적으로 3명이 출력되는 것입니다. 예상과 결과가 다르다면 매 반복의 score와 passed_count를 print()로 출력해 흐름을 추적해 보세요.

정리#

조건문과 반복문은 저장된 데이터를 실제 동작으로 연결하는 기본 도구입니다.

  • if·elif·else는 조건을 위에서 아래로 평가하고 실행 경로를 선택합니다.
  • for는 목록의 항목을 하나씩 처리하거나 정해진 범위를 순회합니다.
  • while은 조건을 매번 다시 확인하며, 조건이 참인 동안 반복합니다.
  • 들여쓰기는 어떤 코드가 조건문이나 반복문에 속하는지를 결정합니다.
  • 반복이 끝나는 조건과 여러 분기의 평가 순서를 확인하면 흔한 오류를 줄일 수 있습니다.

처음에는 코드를 바로 작성하기보다 “무엇을 검사하고, 어떤 경우에 실행하며, 언제 멈추는가?”를 한 문장씩 적어 보세요. 그 문장을 if, for, while로 옮기는 과정이 실행 흐름을 설계하는 출발점입니다.