반복 제어문

이 장에서는 for, while, break, continue 문에 대해서 알아본다.

for 문

거북이를 이용하여 정사각형을 그리는 프로그램을 생각해보자.

import turtle

angela = turtle.Turtle() # angela 거북이 만들기

angela.forward(100)
angela.left(90)
angela.forward(100)
angela.left(90)
angela.forward(100)
angela.left(90)
angela.forward(100)
angela.left(90)

turtle.mainloop()

앞으로 이동과 왼쪽으로 회전을 4번 반복하면 정사각형을 그릴 수 있다. 이러한 반복을 할 수 있게 하는 것이 for문이다. 위의 반복된 문장을 간단히 다음과 같이 사용할 수 있다.

import turtle

angela = turtle.Turtle() # angela 거북이 만들기

for i in [0, 1, 2, 3]: # for 반복문 선언
    angela.forward(100) # 들여쓰기로 for 구역 선언
    angela.left(90)

turtle.mainloop()

for라는 예약어로 시작하며 다음은 반복 변수 i가 나오고 예약어 in 다음에 리스트 [0, 1, 2, 3](반복가능한 객체)가 나오고 콜론 :으로 머리부분을 끝내고 다음 줄로 가서 들여쓰기로 반복문 몸통부분이 선언된다.

for <반복변수이름> in <반복가능객체>:
    반복문 몸통 # 들여쓰기로 구역을 구분한다.

for문이 시작되면 리스트(반복가능한 객체) 안에 있는 항목을 반복 변수 i에게 넘겨주고 반복문 몸통 부분을 실행한다. 반복문 몸통부분 끝에 다다르면 다시 리스트에 있는 다음 항목을 반복 변수에게 넘겨주고 몸통 부분을 끝까지 실행한다. 이러한 반복은 리스트에 있는 항목들을 모두 한번씩 거치면 끝이나고 for문 다음 문장을 실행하게 된다. 위 예제에서 for문이 실행되면 리스트 [0, 1, 2, 3]에서 첫번째 항목 0이 변수 i에 할당되어 angela.forward(100)angela.left(90)이 차례대로 실행되고 다시 for문으로 가서 리스트 안에 있는 다음 항목 1이 변수에 할당되고 마찬가지로 몸통부분인 angela.forward(100)angela.left(90)이 실행된다. 이런식으로 리스트 마지막 항목 3i에 할당된 후 몸통 부분이 실행되면 더 이상 리스트 항목을 거칠 것이 없으므로 for문을 끝내고 다음 문장인 turtle.mainloop()를 실행하게 된다.

리스트 [0, 1, 2, 3]을 사용하지 않고 range(4) 함수를 이용할 수 있다. range(n) 은 0부터 n-1까지 정수를 하나씩 차례로 반환한다.

for i in range(4):
    print(i) # i=0, 1, 2, 3을 차례로 출력한다.

정사각형 그리는 프로그램에서 for문장을 다음과 같이 변경한다면 어떤 도형이 그려질지 생각해보자.

for color_ in ["yellow", "red", "purple", "blue"]:
    angela.color(color_) # 거북이 펜색깔 변경
    angela.forward(100) # 들여쓰기로 for 구역 선언
    angela.left(90)

리스트(list) 맛보기

리스트는 여러 가지 객체들을 하나의 묶음으로 담아 놓는 객체이다. 리스트를 만드는 간단한 방법은 대괄호 [] 안에 담고 싶은 객체들을 쉼표로 나열하면 된다.

x = [1, 'a', "안녕", 3.4] # 리스트

리스트 [1, 'a', "안녕", 3.4]를 변수 x에 할당한다. 리스트 안에 있는 원소들을 접근하기 위해서는 인덱스를 이용한다. 인덱스란 리스트 안의 원소들의 위치를 0보다 크거나 같은 정수로 표현한 것을 말한다. 위 리스트 x에서 원소 1은 인덱스가 0이고 'a'는 인덱스가 1이고 "안녕"은 2, 3.4은 인덱스가 3이다. 따라서 리스트 안의 첫번째 원소를 접근하고 싶으면 x[0]이라고 하면된다.

In [6]:
x = [1, 'a', "안녕", 3.4]
x[0]
Out[6]:
1

리스트가 포함하고 있는 원소의 갯수를 알고 싶으면 내장함수 len()를 이용하면 된다.

In [7]:
len(x)
Out[7]:
4

리스트에 관해서는 앞으로 나올 데이터 형에서 자세히 다룬다.

직접하기

  • for문을 이용하여 리스트 x = [1, 'a', "안녕", 3.4]의 원소들을 한 줄에 하나씩 출력해보자.

  • 거북이와 for문을 이용하여 4개의 원을 꽃잎 모양으로 만들어 보자.

  • 거북이와 for문을 이용하여 한 변의 길이가 300인 별을 만들어 보자.

나선형 문자 출력

거북이를 이용하여 나선형으로 문자를 출력하는 프로그램을 작성하자.

import turtle

 = turtle.Screen()
.bgcolor("black")

연필 = turtle.Pen()
색깔들 = ["red", "yellow", "blue"]

문자열 = ["한반도", "평화", "통일"]

for x in range(1, 60):
    연필.pencolor(색깔들[x % len(문자열)])
    연필.penup()
    연필.forward(x * 5)
    연필.pendown()
    연필.write(문자열[x % len(문자열)], font=("Arial", int((x + 4) / 4), "bold"))
    연필.left(360 / len(문자열) + 5)
.mainloop()
  • = turtle.Screen()과 같이 변수 이름()으로 한글을 사용할 수 있다.
  • 창.bgcolor("black")을 이용하여 배경색을 검은색으로 만든다.
  • turtle.Pen()을 이용하여 연필 객체를 만든다. Pen()은 앞에서 사용했던 Turtle()과 같은 명령어이다.
  • 색깔들 = ["red", "yellow", "blue"]를 이용해 색깔 리스트를 만든다.
  • 문자열 = ["한민족", "평화", "통일"]을 이용해 문자열들을 담을 변수 문자열을 만든다.
  • for 문을 이용해 x가 1부터 59까지 반복하게 한다.
  • 색깔들[x % len(문자열)]을 분석해보자. len(문자열)문자열 리스트가 가지고 있는 항목들의 갯수, 즉 3을 반환한다. 그리고 x % len(문자열)x % 3이고 이것은 x를 3으로 나눴을 때 나머지를 뜻하는 것이므로 0, 1, 2중의 하나가 된다.
  • font = (폰트이름, 폰트크기, 폰트타입)

거북이를 이용하여 임의로 만든 수가 양수이면 왼쪽으로 50만큼, 그렇지 않으면 오른쪽으로 50만큼 이동하는 것을 30번 반복하는 프로그램을 만들어 보자.

import random
import turtle

rdg = random.Random() # 임의의 수를 만들 객체 만들기

jisoo = turtle.Turtle() # jisoo 거북이 만들기

for _ in range(30):
    jisoo.forward(50) # 50만큼 거북이 움직이기

    x = rdg.randint(-1, 1) # -1보다 크거나 같고 1보다 작거나 같은 임의의 정수
    if x > 0:
        jisoo.left(90) # 양수이면 왼쪽으로 회전
    else:
        jisoo.right(90) # 양수가 아니면 오른쪽으로 회전

turtle.mainloop()

import random을 이용하여 임의의 수를 만들 수 있는 모듈 random을 불러온다. rdg = random.Random() 함수를 이용하여 임의의 수를 만들 수 있는 객체(random generator)를 만들어 rdg 변수에 할당한다. 현재 위치에서 50만큼 앞으로 움직인다. x = rdg.randint(-1, 1)-11사이의 정수 중 임의의 정수를 하나 만들어 x 변수에 할당한다. if 문장을 이용하여 만들어진 임의의 수 x가 양수이면 왼쪽으로 90도 회전하고, 그렇지 않으면 오른쪽으로 90도 회전한다. for _ in range(30):을 이용하여 30번 반복한다.

거북이를 이용하여 원 위에 일정한 간격으로 거북이 발자국을 찍는 프로그램을 만들어보자.

import turtle

angela = turtle.Turtle() # angela 거북이 만들기

r = 100 # 반지름 100인 원
n = 10 # n개의 발자국

angela.shape('turtle') # 거북이 모양
angela.penup() # 선을 그리지 않는다.
angela.sety(-r) # 처음 시작하는 y 좌표를 -r로 설정

for i in range(n): # n번 반복
    angela.stamp() # 발자국 찍기
    angela.circle(r, 360 / n) # 반지름 r인 원 위에서 360/n도 회전
turtle.mainloop()
  • 원의 반지름 r과 원 위에 찍을 발자국의 개수 n을 설정한다.
  • turtle.shape('turtle')를 이용하여 거북이 모양으로 모양을 변경한다.
  • penup()을 이용하여 움직일 때 선을 그리지 않게 설정한다.
  • sety(y좌표값)는 거북이가 위치하는 y좌표를 설정한다.
  • stamp()를 이용하여 현재 거북이 모양을 남긴다.
  • circle(r, t) 반지름 r인 원에서 각도 t 만큼 회전이동한다. 여기서는 r=100이고 360/10=36도 만큼 회전하게 된다.
  • for i in range(n):문을 이용해서 n번 반복한다.

중첩 for 문

for 문 안에 for 문을 사용할 수 있다. 바깥 for 문 반복 하나 하나에 대해서 안쪽 for 문이 모두 실행이된다.

In [1]:
for i in range(3):
    for j in range(3):
        print("i = {}, j = {}".format(i, j))
i = 0, j = 0
i = 0, j = 1
i = 0, j = 2
i = 1, j = 0
i = 1, j = 1
i = 1, j = 2
i = 2, j = 0
i = 2, j = 1
i = 2, j = 2

직접하기

  • 구구단을 다음과 같이 출력하는 프로그램을 작성하시오.

    2 x 1 = 2
    2 x 2 = 4
    ...
    9 x 9 = 81
    

while 문

리스트에 있는 항목들을 하나씩 모두 살펴보면서 반복을 하는 for문과 다르게 while 문은 조건문이 참인 동안 반복을 하는 문장이다. while 문은 다음과 같이 사용한다.

while <조건문>:
    <조건문이 참인 동안 실행되는 문장>

다음은 0부터 5까지 더하는 프로그램이다.

n = 5
sum_ = 0
i = 0

while i <= n:
    sum_ += i
    i += 1
print(sum_)
  • while 조건문 i <= n이 거짓이면 while문을 마치고, 다음 문장 print(sum_)이 실행이 된다.
  • 조건문이 참이면 몸통(들여쓰기 구역)이 한 줄씩 실행된 후 다시 조건문을 실행하여 거짓이면 while문을 끝내고 다음 문장이 실행이 되고 참이면 반복을 계속하게 된다.

while 문을 사용할 때는 while 몸통 구역에 while 조건문이 거짓이 되도록 하는 문장을 만들어야 한다. 그렇지 않으면 무한히 while문을 반복하게 되어 프로그램이 종료되지 않게 된다. 무한 반복을 끝내는 방법으로 조건문을 거짓으로 만드는 것 외에 break 예약어를 이용하여 반복을 끝낼 수도 있다.

break 문

반복문 안에서 break문을 만나면 즉시 반복문을 끝내고 다음 문장을 실행한다. 0부터 5까지 더하는 프로그램은 break문을 이용하여 다음과 같이 바꿀 수 있다.

n = 5
sum_ = 0
i = 0

while True:
    if i > n:
        break
    sum_ += i
    i += 1
print(sum_)

for 반복문에서도 break 문을 사용할 수 있다.

for i in [12, 16, 17, 24, 29]:
    if i % 2 == 1: # 홀수이면
        break # 반복문을 끝낸다.
    print(i) # 짝수 출력
print("반복문 종료")

리스트 안에 있는 숫자들이 홀수이면 반복문을 즉시 끝내고, 그렇지 않으면 숫자를 출력하게 된다.

직접하기

  • 거북이를 이용하여 사용자로부터 영문자 을 누르고 엔터치면 왼쪽으로 100만큼, r을 누르고 엔터치면 오른쪽으로 100만큼, q를 누르고 엔터치면 그리기를 멈추도록 하는 프로그램을 작성하자.

다음은 숫자를 맞추는 프로그램이다.

import random # 임의의 숫자 만드는 모듈 불러오기

rng = random.Random() # 임의의 숫자 만드는 객체 rng 만들기
number = rng.randrange(1, 1000) # 1보다 크거나 같고 1000보다 작은 임의의 수를 number에 할당.

guesses = 0 # 시도한 횟수
message = ""

while True:
    guess = int(input(message + "\n1보다 크거나 같고 1000보다 작은 수를 입력하세요: "))
    guesses += 1
    if guess > number:
        message += str(guess) + "은(는) 너무 크네요.\n"
    elif guess < number:
        message += str(guess) + "은(는) 너무 작아요.\n"
    else:
        break

print("\n\n축하합니다. "+str(guesses)+"번만에 맞췄습니다! \n\n")

continue 문

반복문 중에서 continue 문을 만나면 continue문 아래에 있는 문장은 실행되지 않고 다음 반복을 실행한다. 다음은 리스트에서 짝수만 출력하는 프로그램이다.

for i in [12, 16, 17, 24, 29, 30]:
    if i % 2 == 1: # 홀수이면
        continue # 아래 반복문 문장들은 무시하고 다음 반복을 실행한다.
    print(i)
print("반복문 끝.")

홀수이면 continue문을 만나게 되어 아래에 있는 print(i)를 실행하지 않고 다음 반복 항목을 실행하게 된다.

연습

  1. 일요일부터 토요일까지를 0,1,2,3,4,5,6 숫자로 대신한다고 할 때, 숫자를 입력받아 요일을 출력하는 프로그램을 작성하시오.

  2. 수요일 낮에 휴가를 출발하여 137밤 자고 돌아올 때, 돌아오는 요일을 출력하는 프로그램을 작성하시오.

  3. 사용자에게 숫자를 입력받아 거북이와 for문을 이용하여 정다각형을 그리는 프로그램을 작성하시오.

  4. 거북이를 이용해 다음 그림을 그리시오.

  5. 사용자로부터 숫자를 입력받아 숫자를 구성하는 수중에서 짝수의 갯수를 세는 프로그램을 작성하시오. 예를 들면 입력받은 수가 12345이면 짝수는 2, 4 두 개이다.

  6. 임의의 두 수를 만들고 그 두 수의 뺄셈 문제를 내고 사용자에게 답을 적게 만들고 답이 올바른지 검사하는 프로그램을 작성하시오.

  7. 리스트 numbers = [12, 10, 32, 3, 66, 17, 42, 99, 20] 가 주어질 때 각 숫자를 한 줄에 하나씩 출력하는 프로그램을 작성하시오.

  8. 위 문제에서 리스트에 있는 모든 숫자의 합을 계산해서 출력하는 프로그램을 작성하시오.

  9. 원의 반지름과 중심을 임의의 수를 이용하여 생성하고 반복문을 이용하여 10개 그리는 프로그램을 작성하시오.

  10. 시험 점수가 다음과 같이 리스트 scores = [83, 75, 74.9, 70, 69.9, 65, 60, 59.9, 55, 50, 49.9, 45, 44.9, 40, 39.9, 2, 0] 로 주어졌을 때 아래 기준에 맞춰 학점을 출력하는 프로그램을 작성하시오.

점수 학점
>= 80 A+
[70, 80) A
[60, 70) B+
[50, 60) B
[40, 50) C+
< 40 C