8. 반복문#

반복 명령문을 이용하면 지정된 명령문을 반복 실행시킬 수 있다. 파이썬 프로그래밍 언어는 세 가지 방식으로 명령문을 반복시킬 수 있다.

  • for 반복문

  • while 반복문

  • 재귀 함수

여기서는 3.7절 에서 소개한 for 반복문과 while 반복문의 보다 많은 활용 예제와 고급 활용법을 소개한다. 재귀 함수는 20장에서 다룬다.

8.1. 리스트와 for 반복문#

리스트를 for 반복문과 함께 사용하면 0번 인덱스 위치의 항목에서부터 하나씩 오른쪽으로 이동하며 반복문을 적용한다. 아래 코드는 one2five에 포함된 항목을 모두 더한 결과를 계산한 후에 출력한다.

one2five = [1, 2, 3, 4, 5]

sum_list = 0 

for item in one2five:
    sum_list += item

print(sum_list)
15

코드에 포함된 아래 for 반복분이 실행되면 item 변수는 먼저 0번 인덱스의 항목인 1을 가리킨다.

for item in one2five:
    sum_list += item

따라서 sum_list가 1을 가리키게 되고 다시 반복문의 본문의 처음으로 돌아간다. 이제 item은 1번 인덱스 항목인 2를 가리키고 반복문의 본문을 다시 실행한다.

이 과정을 item이 리스트의 마지막 항목은 5를 가리키고 반복문의 본문을 실행할 때까지 반복하면 for 반복문의 실행을 종료하고 다음 명령문으로 넘어가서 그때까지의 누적합을 가리키는 sum_list를 출력한다.

Python Tutor 활용 for 반복문 설명

아래 그림은 위 코드의 for 반복문이 실행되는 순간 선언된 변수들이 가리키는 값을 보여준다. sum_list는 아직 초기화 상태이고 item은 1을 가리키고 있다.

<그림 출처: Python Tutor>

반면에 아래 그림은 for 반복문이 2번 실행되어 sum_list는 3을, item은 2를 가리키고 있음을 보여준다.

<그림 출처: Python Tutor>

반복문이 계속 실행되어 item이 리스트의 마지막 항목인 5를 가리키면 sum_list는 15를 가리키며 반복문이 종료된다. 그러면 다음 명령문인 print(sum_list)가 실행되어 15가 출력된다(아래 그림 참고).

<그림 출처: Python Tutor>

예제

1부터 10까지의 정수 중에서 홀수들의 합을 계산하라. 단, 1부터 10까지의 정수로 구성된 리스트에 for 반복문을 적용한다.

먼저 1부터 10까지의 정수로 구성된 리스트를 가리키는 변수 one2ten을 선언한다.

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

앞서 1부터 5까지의 합을 계산한 프로그램과 거의 비슷하게 프로그램을 작성할 수 있다.

sum_list = 0
for item in one2five:
    sum_list += item

다만 item이 가리키는 항목이 홀수일 때만 sum_list에 더한다는 점이 다르다. item이 가리키는 값이 홀수인지 여부를 판단하는 표현식은 item % 2 == 1이며, 홀수일 때만 sum_list에 더하는 코드는 다음과 같다.

if item % 2 == 1:
    sum_list += item

정리하면 아래 프로그램을 이용하여 1부터 10까지 정수 중에서 홀수들의 합을 계산할 수 있다.

odd_sum = 0

for num in one2ten:
    if num % 2 == 1: 
        odd_sum += num

print(odd_sum)
25

1부터 10까지의 정수 중에서 홀수들의 합이 25로 계산된다. 그런데 위 코드가 정말로 1, 3, 5, 7, 9의 합을 계산했는지 결과만으로는 알 수 없다. 이를 확인하기 위해 코드를 실행할 때 sum_list에 더해지는 수를 함께 출력하도록 프로그램을 수정해보자.

홀수인 경우 화면에 출력되도록 print() 함수를 이용한다. 단, end=" " 키워드 인자를 이용하여 홀수들의 출력이 한 줄에 이루어지도록 하였다. 끝에서 둘쨋줄의 print() 함수는 마지막 줄의 출력을 구분하는 줄바꿈용으로 사용된다.

odd_sum = 0

print("더해지는 수:", end=" ")
for num in one2ten:
    if num % 2 == 1: 
        print(num, end=" ")
        odd_sum += num   

print("")
print("1부터 10까지의 정수 중에서 홀수들의 합:", odd_sum)
더해지는 수: 1 3 5 7 9 
1부터 10까지의 정수 중에서 홀수들의 합: 25

8.2. 리스트와 while 반복문#

리스트를 대상으로 while 반복문을 실행하려면 리스트의 길이, 즉 리스트에 포함된 항목들의 개수와 인덱싱을 활용한다. 이유는 for 반복문과는 달리 while 반복문은 리스트의 항목을 직접 가리키는 기능을 제공하지 않기 때문이다.

아래 코드는 위 for 반복문과 동일한 기능을 수행한다. len() 함수가 리스트에 포함된 항목들의 개수를 반환한다. 인덱스를 가리키는 변수 i의 값을 반복문이 한 번 실행될 때마다 인위적으로 1씩 키워줘야 하고, 언제 반복이 멈춰야 하는지를 논리식으로 명시해줘야 하는 점이 for 반복문과 다르다.

one2five = [1, 2, 3, 4, 5]

sum_list = 0
i = 0
while i < len(one2five):
    item = one2five[i]
    sum_list += item 
    i += 1           

print(sum_list)
15

코드에 포함된 아래 while 반복분이 실행될 때 i 변수는 먼저 0을 가리키기에 item 변수는 0번째 인덱스의 값인 1을 가리킨다.

while i < len(one2five):
    item = one2five[i]
    sum_list += item 
    i += 1           

따라서 sum_list가 0이 아닌 1을 가리키게 된다. 이후 i가 1로 바뀌고 다시 반복문의 본문의 처음으로 돌아간다. 이때 item은 1번 인덱스 항목인 2를 가리키고 반복문의 본문을 다시 실행한다.

이 과정을 i가 4를 가키릴 때까지 반복하면 sum_listone2five 리스트의 0번 인덱스의 항목부터 마지막 항목까지 더한 값을 가리키게 되고 i가 5, 즉 one2five의 길이와 같아지게 되어 while 반복문의 실행을 종료하고 다음 명령문으로 넘어간다.

Python Tutor 활용 while 반복문 설명

아래 그림은 위 코드의 while 반복문이 실행되어 item 변수가 선언된 순간에 sum_listi는 아직 초기화 상태이고 item은 0번 인덱스 항목인 1을 가리키고 있음을 보여준다.

<그림 출처: Python Tutor>

반면에 아래 그림은 while 반복문이 세 번째로 실행되어 i는 2, item은 3을 가리키지만 sum_list는 아직 업데이트 이전 상태를 보여준다.

<그림 출처: Python Tutor>

while 반복문이 계속 실행되어 i가 5가 되면 논리식 i < len(one2five)가 거짓이 되고 반복문을 더 이상 실행하지 않는다. sum_list는 모든 항목이 더해진 상태인 15를 가리킨다.

<그림 출처: Python Tutor>

위 코드에서 사용된 item 변수는 앞서 for 코드와의 비교를 위해 사용되었지만 굳이 필요하진 않고 아래 코드에서처럼 i번 인덱스 항목을 직접 sum_list에 더해도 된다.

one2five = [1, 2, 3, 4, 5]

sum_list = 0
i = 0 
while i < len(one2five):
    sum_list += one2five[i]
    i += 1

print(sum_list)
15

8.3. range() 함수와 for 반복문#

range() 함수는 for 반복문과 함께 매우 유용하게 사용된다.

8.3.1. range() 함수#

range() 함수는 리스트와 매우 유사한 값을 생성한다. 예를 들어, range(10)는 0부터 10 이전까지 정수, 즉 0부터 9까지의 정수를 포함하는 리스트와 유사한 값을 생성한다.

range(10)
range(0, 10)

range 함수? 클래스?

range 는 실제로는 함수가 아니며 16장에서 소개하는 개념인 클래스로 선언되었다. 하지만 매우 자연스럽게 함수처럼 활용되기에 함수로 많이 불리며 여기서도 그 관행을 따른다.

0을 첫째 인자로, 10을 둘째 인자로 사용해도 동일한 모양의 값을 생성한다.

range(0, 10)
range(0, 10)

range() 함수가 생성하는 값의 자료형은 range 이다.

type(range(10))
range

그런데 range(10)의 내부를 바로 보여주지는 않는다.

print(range(10))
range(0, 10)

리스트로의 형변환

range 자료형의 값이 내부를 바로 보여주지 않는 이유는 19장에서 설명하지만 지금은 전혀 중요하지 않다. 대신 리스트로의 형변환을 통해 range 자료형의 값에 포함되는 항목들을 확인할 수 있다는 사실은 잘 기억해야 한다.

list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range() 함수는 for 반복문에서 리스트 대신에 매우 유용하게 활용된다. 예를 들어 아래 코드는 range(10)이 리스트 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 대신 사용될 수 있음을 보여준다. 이유는 item 변수에 0부터 9까지의 정수가 차례대로 할당되기 때문이다.

for item in range(10):
    print("item에 할당된 값:", item)
item에 할당된 값: 0
item에 할당된 값: 1
item에 할당된 값: 2
item에 할당된 값: 3
item에 할당된 값: 4
item에 할당된 값: 5
item에 할당된 값: 6
item에 할당된 값: 7
item에 할당된 값: 8
item에 할당된 값: 9

range() 함수의 인자

range() 함수는 최소 하나에서 최대 세 개의 위치 인자를 받으며, 인자의 개수에 따라 각 인자의 역할이 정해진다.

경우 1: 한 개의 인자

range(10)range(0, 10)과 동일한 모양의 값을 생성한다고 말했듯이 하나의 인자만 사용하면 첫째 인자가 0인 두 개의 인자를 사용하는 경우와 동일하다.

경우 2: 두 개의 인자

range() 함수가 표현하는 구간의 시작을 0이 아닌 다른 정수로 하려면 반드시 두 개의 인자를 사용해야 한다. 예를 들어, 아래 코드는 1부터 10까지의 정수로 구성된 리스트에 해당하는 값을 계산한다.

one2ten_range = range(1, 11)

실제로 리스트로 형변환하면 2부터 10까지의 정수를 포함한 리스트로 계산된다.

list(one2ten_range)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

위 사실을 이용하면 1부터 10까지의 정수의 합을 계산하는 코드를 아래처럼 for 반복문과 range() 함수를 이용하여 간단하게 구현할 수 있다.

sum = 0
for num in range(1, 11):
    sum += num
    
print("1부터 10까지 정수의 합:", sum)
1부터 10까지 정수의 합: 55

경우 3: 세 개의 인자

range() 함수에 세 개의 인자를 사용하면 첫째, 둘째 인자의 의미는 이전과 동일하다. 반면에 셋째 인자는 보폭을 가리킨다. 예를 들어 아래 코드는 1부터 9까지의 정수 중에서 홀수만을 대상으로 하는 리스트를 생성한다. 이유는 보폭이 2로 지정되었기에 1부터 시작해서 1씩이 아닌 2씩 증가시켜 생성되는 값, 즉 홀수들만을 range 자료형의 값에 포함시키기 때문이다.

list(range(1, 10, 2))
[1, 3, 5, 7, 9]

보폭을 인자로 사용하려면 반드시 세 개의 인자를 사용해야 한다. 예를 들어 0부터 10까지의 짝수로 구성된 리스트에 포함시키려면 다음과 같이 한다.

list(range(0, 11, 2))
[0, 2, 4, 6, 8, 10]

두 개의 인자를 사용할 때와는 다르게 첫째 인자가 0이어도 반드시 명시해야 한다. 그렇지 않으면 다음과 같이 엉뚱한 결과를 얻게 된다.

list(range(11, 2))
[]

음의 보폭

바로 앞서 언급한 코드는 구간의 시작이 끝보다 크다. 이런 경우 보폭을 지정하지 않거나 양수로 지정하면 아무런 값도 포함되지 않는다.

list(range(11, 2))  # list(range(11, 2, 1)) 과 동일
[]
list(range(11, 2, 2))
[]

이유는 11에서부터 1씩 또는 2씩 커지면서 2 이전까지의 구간에 속하는 정수는 없기 때문이다. 하지만 음의 보폭을 지정하면 크기가 작아지는 정수들을 항목으로 갖는다.

예를 들어 아래 코드는 11에서부터 0 이전까지, 즉 1까지의 정수 중에서 홀수만을 항목으로 갖는 리스트를 반환한다. 단, 구간의 끝이 둘째 인자의 이전인데 이때 이전의 의미는 보폭이 양의 정수인지, 음의 정수인지에 따라 달라짐에 유의한다.

list(range(11, 0, -2))
[11, 9, 7, 5, 3, 1]

8.3.2. 리스트 대 range() 함수#

리스트가 주어졌을 때 for 반복문을 이용하면 리스트 각각의 항목에 대해 동일한 코드를 실행하도록 할 수 있다. 예를 들어, 아래 코드는 2부터 10까지의 짝수들의 합을 계산한다. 리스트 각각의 항목에 대해 반복되는 아래 명령문이 반복된다.

sum = sum + item

즉, sum 변수에 리스트 각각의 항목을 더한 값을 재할당하는 과정을 반복한다.

two2ten_even = [2, 4, 6, 8, 10]

sum = 0
for item in two2ten_even:
    sum = sum + item
    
print("2부터 10까지 짝수들의 합:", sum)
2부터 10까지 짝수들의 합: 30

그런데 2부터 1만까지, 아니 2부터 1억까지의 짝수들의 합을 계산하려면 one2ten_even과 유사한 변수를 선언하기 위해 항목을 5천 개 또는 5천만 개를 갖는 리스트를 먼저 표현해야 한다. 하지만 이런 일을 사람이 직접 타이핑하기에는 매우 지난하거나 불가능하다.

파이썬을 포함한 대부분의 프로그래밍 언어는 이런 경우를 간단하게 처리할 수 있는 기능을 제공한다. 파이썬의 경우엔 range() 함수를 활용한다. 예를 들어 2부터 10까지의 짝수들의 합을 아래와 같이 계산할 수 있다.

sum = 0
for item in range(2, 11, 2):
    sum = sum + item
    
print("2부터 10까지 짝수들의 합:", sum)
2부터 10까지 짝수들의 합: 30

그리고 위 코드에서 하나의 숫자만 수정해서 2부터 1억까지의 짝수들의 합을 계산할 수 있다.

sum = 0
for item in range(2, 100_000_001, 2):
    sum = sum + item
    
print("2부터 1억까지 짝수들의 합:", sum)
2부터 1억까지 짝수들의 합: 2500000050000000

이처럼 임의의 정수 n에 대해 range(n), range(2, n), range(10, n, 3) 등은 일정한 방식으로 특정 구간에 속하는 값들의 모음을 나타낸다는 점에서 리스트와 많이 다르다.

이 성질을 이용하여 예를 들어 다음과 같은 함수를 정의할 수 있다. addition_n() 함수는 2 이상의 양의 정수 n이 주어지면 2부터 n까지의 짝수들의 합을 계산해서 보여준다.

def addition_n(n):
    sum = 0
    for item in range(2, n+1, 2):
        sum = sum + item

    print("2부터", n, "까지 짝수들의 합:", sum)
addition_n(10)
2부터 10 까지 짝수들의 합: 30
addition_n(100)
2부터 100 까지 짝수들의 합: 2550
addition_n(1000)
2부터 1000 까지 짝수들의 합: 250500
addition_n(100000000)
2부터 100000000 까지 짝수들의 합: 2500000050000000

반면에 리스트를 이용해서는 동일한 기능을 갖는 함수를 구현할 수 없다. 이유는 리스트 [2, 4, 6, ..., n] 의 길이가 n에 의존해서 달라지는데 변수 n이 가리키는 값을 모르면 리스트 자체를 선언할 수 없기 때문이다.

8.4. while 반복문 기본 활용법#

for 반복문은 리스트 또는 range() 함수처럼 일정 구간에서 규칙성 있게 변하는 값들을 대상으로 동일한 명령문을 반복 수행할 때 사용한다. 앞서 본 것처럼 while 반복문도 유사하게 활용될 수 있지만 while 반복문은 일정 구간이나 규칙이 없어도 특정 조건이 만족되는 동안 계속해서 동일한 명령문을 반복 실행하고자 할 때 사용할 수 있다.

예를 들어 아래 “수 알아맞히기 게임” 코드는 1부터 100 사이의 정수 하나를 입력하면 입력한 값을 secret 변수에 할당된 17과 비교해서 맞다, 크다, 또는 작다에 해당하는 경우에 맞게 지정된 문장을 출력한다.

print("수 알아맞히기 게임에 환영합니다.")

secret = 17
guess = int(input("1부터 100 사이의 정수 하나를 입력하세요: "))

if guess == secret:
    print("맞았습니다!")
elif guess > secret:
    print("너무 커요!")
else:
    print("너무 작아요!")

print("게임 종료!")
수 알아맞히기 게임에 환영합니다.
1부터 100 사이의 정수 하나를 입력하세요: 33
너무 커요!
게임 종료!

그런데 위 코드는 답을 한 번만 입력하면 맞든 틀리든 바로 종료한다. 따라서 정답을 입력할 때가지 반복해서 사용자로부터 입력을 받도록 하는 게 좋다. 그런데 몇 번 입력을 받으면 되는지 미리 알 수 없다. 이처럼 반복 횟수를 미리 정할 수 없지만 특정 조건이 만족될 때까지 지정된 명령문이 반복 실행되도록 하려면 while 반복문을 사용한다. 예를 들어 아래 코드는 guess != secret이 참인 동안, 게임 참여자가 secret에 저장된 값을 입력할 때까지 반복해서 정수를 입력하도록 한다.

게임 참여자가 입력한 값이 틀리면 출력되는 정보에 따라 보다 큰 값 또는 보다 작은 값을 입력하도록 유도해서 게임 참여자가 예측 범위를 줄여 나가면서 결국에는 정답을 입력할 수 있게 된다. while guess != secret이 실행되기 전에 guess = -1로 변수 할당문을 선언하는 이유는 while 반복문이 최소 한 번은 실행되도록 만들기 위해서이다.

print("수 알아맞히기 게임에 환영합니다.")

secret = 17
guess = -1   # 이어지는 while 반복문이 최소 한 번은 실행되도록 함

while guess != secret:
    guess = int(input("1부터 100 사이의 정수 하나를 입력하세요: "))
    if guess == secret:
        print("맞았습니다!")
    elif guess > secret:
        print("너무 커요!")
    else:
        print("너무 작아요!")

print("게임 종료!")
수 알아맞히기 게임에 환영합니다.
1부터 100 사이의 정수 하나를 입력하세요: 33
너무 커요!
1부터 100 사이의 정수 하나를 입력하세요: 15
너무 작아요!
1부터 100 사이의 정수 하나를 입력하세요: 17
맞았습니다!
게임 종료!

8.5. breakcontinue#

for 또는 while 반복문의 실행 도중에 break 명령문과 continue 명령문이 실행되면 반복문의 실행을 중간에 중단시키거나 특정 경우를 건너뛰도록 한다.

break 명령문

break 명령문은 for 또는 while 반복문의 실행을 중지시킨다. 예를 들어, 아래 프로그램을 실행하면 1부터 9까지의 정수를 대상으로 차례대로 3의 배수 여부를 판단한다. num 변수에 차례대로 1, 2, 3, … 를 할당할 때마다 3의 배수 여부를 판단한다.

  • 3의 배수가 아닐 때: num이 가리키는 값이 3의 배수가 아님을 출력함.

  • 3의 배수인 경우: 3의 배수를 찾았다고 알린 후 바로 break 명령문이 실행되어 반복문이 종료됨. 즉, "3의 배수 찾았음"을 출력하는 바로 다음 줄에 위치한 print() 함수의 호출은 실행되지 않음.

즉, num 변수가 1 또는 2를 가리킬 때는 3의 배수가 아님을 알리고 3을 가리킬 때는 3의 배수임을 알리고 바로 for 반복문의 실행을 종료시킨다. 원래는 num 변수가 4, 5, … 등을 가리키는 경우도 반복해야 하지만 더이상 그러지 않는다.

이후 마지막 줄의 print() 함수 호출은 실행되어 프로그램의 종료를 알린다. break는 자신을 포함한 반복문의 실행을 멈추게 하지만 전체 프로그램은 차례대로 끝까지 실행된다.

for num in range(1, 10):
    if num % 3 != 0:
        print(num, "은(는) 3의 배수 아님!")
    else:
        print(num, "은(는) 3의 배수!")
        break
        print("3의 배수 찾았음")
        
print("프로그램 종료!")
1 은(는) 3의 배수 아님!
2 은(는) 3의 배수 아님!
3 은(는) 3의 배수!
프로그램 종료!

아래 코드는 위 프로그램을 while 반복문으로 구현하였으며 실행되는 과정은 위 코드와 동일하다. 즉, num에 3이 할당되어 3의 배수를 가리키는 순간 break 명령문이 실행되어 반복문이 바로 멈추고 마지막 줄의 print() 함수가 호출된다.

num = 1

while num < 10:
    if num % 3 != 0:
        print(num, "은(는) 3의 배수 아님!")
    else:
        print(num, "은(는) 3의 배수!")
        break
        print("3의 배수 찾았음")
        
    num += 1
        
print("프로그램 종료!")
1 은(는) 3의 배수 아님!
2 은(는) 3의 배수 아님!
3 은(는) 3의 배수!
프로그램 종료!

continue 명령문

continue 명령문이 반복문 실행 도중에 실행되면 반복문의 실행을 중지하고 다시 반복문의 처음으로 돌아간다.

  • for 반복문: 현재 처리중인 경우를 바로 건너 뛰고 다음 경우로 넘어감.

  • while 반복문: while 반복문의 처음으로 바로 돌아감.

아래 프로그램을 실행하면 1부터 9까지의 정수를 대상으로 차례대로 3의 배수 여부를 판단한다.

num이 차례대로 1, 2, 3, … 등을 할당받을 때마다 3의 배수 여부를 판단한다.

  • num에 할당된 값이 3의 배수인 경우: 3의 배수임을 확인하는 문자열 출력

  • num에 할당된 값이 3의 배수가 아닌 경우: continue 명령문이 실행되어 바로 아랫줄의 print() 명령문을 실행하지 않고 반복문의 다음 경우로 이동함. 즉, num이 다음 항목을 가리키도록 함.

결국 num이 1부터 시작해서 차례대로 값을 할당받으면 1, 2, 4, 5, 7, 8의 경우는 continue 명령문에 의해 무시되는 효과가 발생한다.

for num in range(1, 10):
    if num % 3 == 0:
        print(num, "은(는) 3의 배수!")
    else:
        continue
        print(num, "은(는) 3의 배수 아님!")

print("1과 10 사이에서 3의 배수를 확인했음!")
3 은(는) 3의 배수!
6 은(는) 3의 배수!
9 은(는) 3의 배수!
1과 10 사이에서 3의 배수를 확인했음!

아래 코드는 위 코드와 동일하게 작동한다. 대신 while 반복문을 사용한다.

num = 0
while num < 10:
    num += 1
    if num % 3 == 0:
        print(num, "은(는) 3의 배수!")
    else:
        continue
        print(num, "은(는) 3의 배수 아님!")
        
print("1과 10 사이에서 3의 배수를 확인했음!")
3 은(는) 3의 배수!
6 은(는) 3의 배수!
9 은(는) 3의 배수!
1과 10 사이에서 3의 배수를 확인했음!

num을 0으로 초기화 하고 num += 1 명령문을 while 반복문이 실행될 때 제일 먼저 실행되도록 함에 주의한다. 그렇지 않으면 num 값을 1씩 증가시키기가 어려질 수 있다. 이유는 num에 3이 할당되는 순간 바로 continue가 실행되어 num이 가리키는 값을 1 증가시킬 기회가 제공되지 않기 때문이다.

예를 들어 아래 코드를 실행하면 반복문의 실행이 멈추지 않는다. 앞서 설명한 대로 num에 3이 할당되는 순간 num을 재할당하지 못하고 다시 반복문의 처음으로 돌아가서 계속해서 num을 가리키게 되기 때문이다.

num = 0
while num < 10:
    if num % 3 == 0:
        print(num, "은(는) 3의 배수!")
    else:
        continue
        print(num, "은(는) 3의 배수 아님!")

    num += 1

print("1과 10 사이에서 3의 배수를 확인했음!")

breakcontinue 명령문의 영향 범위

breakcontinue 명령문은 자신이 포함된 for/while 반복문의 실행만 멈추게 한다. 따라서 실행이 멈춘 반복문에 이어지는 다른 코드는 계속해서 실행된다.

예를 들어 동일한 일을 하는 아래 두 코드를 실행하면 1과 2를 출력한 후에 forwhile 반복문의 실행이 멈춘다. 그리고 마지막 줄에 위치한 print("코드 실행 종료") 명령문이 실행되어 화면에 "코드 실행 종료"가 출력된다.

  • for 반복문

for num in range(1, 5):
    print(num)
    if num == 2:
        break
    
print("코드 실행 종료!")
1
2
코드 실행 종료!
  • while 반복문

num = 1

while num < 5:
    print(num)
    if num == 2:
        break
    num += 1
    
print("코드 실행 종료!")
1
2
코드 실행 종료!

8.6. 무한 반복과 break 명령문#

아래 코드를 실행하면 사용자로부터 계속해서 값을 입력받으며 절대로 멈추지 않는다. 이유는 while True에서 사용된 True 표현식이 항상 참이기 때문이다.

while True:
    line = input('단어입력: ')
    print(line)

print('종료합니다!')

만약 위 코드를 실행했다면 파이썬 실행기를 강제로 종료시키거나 컴퓨터를 꺼야 한다. 이처럼 반복문이 끝나지 않고 계속 실행되는 현상을 무한 반복infinite loop라 하며 경우에 따라 무한 루프라 불리기도 한다.

반면에 아래 코드는 사용자로부터 '중지' 단어가 입력되는 순간 반복문을 중지한다. 그런 다음 마지막 줄의 print() 함수 호출을 실행해서 프로그램의 종료를 알린다.

while True:
    line = input('단어입력: ')
    if line == '중지':
        break
    print(line)

print('종료합니다!')
단어입력: 파이썬
파이썬
단어입력: python
python
단어입력: 중지
종료합니다!

무한 반복은 게임 프로그래밍에서 자주 사용된다. 게임 종료 시점은 게임의 전개 과정에 따라 달라지기에 미리 알 수 없다. 따라서 게임 진행 전체를 관장하는 코드는 기본적으로 while True로 시작하는 무한 반복을 활용한다. 단, 게임이 종료되는 조건이 되면 break 명령문 등과 같이 반복문의 실행을 종료시키거나 프로그램 자체를 종료시키는 특정 명령문이 실행되도록 해야 한다.

예를 들어, 거북이 경주 게임에서 두 마리의 거북이가 목표 지점에 다다르기 위해 경주를 한다. 두 마리 중 한 마리의 거북이가 먼저 목표 지점에 다다르면 승자가 결정되고 게임이 멈추는데 그때가 언제인지는 절대로 미리 알 수 없다. 따라서 경주를 진행하는 반복문이 while True로 시작하며 한 마리의 거북이가 목표 지점에 다다르면 반복문의 실행이 멈추도록 break 명령문이 사용되었다.

참고로 아래 거북이 경주 게임 코드는 2차원 컴퓨터 그래픽스를 지원하는 turtle 모듈을 사용하며 구글 코랩에서는 실행되지 않는다. 코드 설명과 실행 환경에 대해서는 9장을 참고한다.

import turtle
import random

# Tina 생성 후 출발점에 위치시키기
tina = turtle.Turtle()
tina.color("green")
tina.shape("turtle")
tina.penup()
tina.goto(-180,50)

# Tommy 생성 후 출발점에 위치시키기
tommy = turtle.Turtle()
tommy.color("blue")
tommy.shape("turtle")
tommy.penup()
tommy.goto(-180,-50)

# Tina의 목표지점에 원 그리고 출발점으로 되돌아오기
tina.goto(170,20)
tina.pendown()
tina.circle(20)
tina.penup()
tina.goto(-180,50)

# Tommy의 목표지점에 원 그리고 출발점으로 되돌아오기
tommy.goto(170,-80)
tommy.pendown()
tommy.circle(20)
tommy.penup()
tommy.goto(-180,-50)

# 게임 실행
def rolling_dice(t):
    t_turn = input("엔터키를 누르면 주사위가 던져집니다!")
    die_outcome = random.randint(1, 6)
    print("주사위 값:", die_outcome)
    print("전진 거리:", 10*die_outcome)
    t.fd(10 * die_outcome)

while True:
    rolling_dice(tina)

    if tina.pos()[0] >= 130:
        tina.write("I won!")
        print("Tina won!")
        break

    rolling_dice(tommy)

    if tommy.pos()[0] >= 130:
        tommy.write("I won!")
        print("Tommy won!")
        break

8.7. 필수 예제#

참고: (필수 예제) 반복문

8.8. 연습문제#

참고: (실습) 반복문