1. 반복문(Loop)

오늘은 반복문(Loop)이라는 것에 대해 알아보도록 하겠습니다. 반복문, 쉽게 생각하면 이름 그대로 반복에 사용되는 녀석입니다. 파이썬에서 지원하는 반복문에는 조건문이 참인가 거짓인가에 따라 반복을 진행하는 while문이라는 것이 존재하고, 리스트나 튜플 같은 순서형 자료의 요소들을 하나씩 가져오면서 반복을 수행하는 for문이 존재합니다. 이 두 가지에 대해서 간단히 알아볼 계획인데, 비슷한 작업이 수 없이도 반복되는 것을 이러한 반복문을 통해서 간단히 해결할 수 있습니다. 먼저 while문에 대해서 먼저 알아보도록 하겠습니다.


2. while문

앞에서 소개한대로 while문은 조건식을 가지는 녀석입니다. 조건식이 참이라면 while문 내부에 있는 블록의 문장을 실행하고, 거짓이면 반복을 멈추고 빠져나옵니다. 우선은 while문의 형태를 먼저 보도록 합시다.

while 조건식:
	문장

위를 보시면 while 다음에 조건식이 오며, 조건식 뒤에는 콜론(:)이 따라붙는다는 것을 알 수 있습니다. 우선은 while문의 간단한 예제를 보도록 합시다.

>>> i = 1
>>> while i <= 10:
	print(i, "번 출력되었습니다.")
	i += 1

1 번 출력되었습니다.
2 번 출력되었습니다.
3 번 출력되었습니다.
4 번 출력되었습니다.
5 번 출력되었습니다.
6 번 출력되었습니다.
7 번 출력되었습니다.
8 번 출력되었습니다.
9 번 출력되었습니다.
10 번 출력되었습니다.

위의 예제를 보시면 조건식에 'i <= 10'이 왔음을 보실 수가 있습니다. 이는 변수 i의 값이 10보다 작거나 같은 경우에 참이 성립되며, 10보다 큰 경우는 거짓에 해당합니다. 그리고 'i += 1'과 같은 코드는 i의 값을 1만큼 증가시키는 'i = i + 1'를 축약한 코드로, 반복문을 빠져나오도록 하기 위해 작성된 코드입니다. 


만약에 while문의 조건식이 처음부터 거짓이면 내부 블록에 있는 문장이 단 한번이라도 실행되지 않습니다. 왜냐하면, while문의 실행 순서는 '조건식을 검사 -> 내부 블록에 있는 문장을 실행 -> 조건식을 검사 -> ...'이러한 순서를 따르기 때문입니다.

위의 while문을 순서도로 나타내면 위와 같을 것입니다. i가 10보다 커지는 순간 거짓으로 넘어가서 반복문을 빠져나와 버립니다. 이해가 되셨나요? 만약에 'i = i + 1'과 같은 구문이 없다면, 조건식은 항상 참으로 성립하게 되어 반복문을 빠져나올수 없을 것입니다. 이렇게 되면 무한 루프에 빠지게 되는데, 무한 루프란 말 그대로 무한히 반복한다는 것입니다. 이런 상황을 피하기 위해서 i의 값을 증가시켜 주는 것입니다.


2-1. break문

이번에는 break문의 설명을 위해 위의 예제를 약간 수정해보도록 하겠습니다.

>>> i = 1
>>> while i <= 10:
	if i == 7:
		break
	print(i, "번 출력되었습니다.")
	i += 1

1 번 출력되었습니다.
2 번 출력되었습니다.
3 번 출력되었습니다.
4 번 출력되었습니다.
5 번 출력되었습니다.
6 번 출력되었습니다.

저기 사용된 break문이 어떤 녀석이냐면, 이 문법을 통해 반복문은 조건식이 거짓이여야 반복을 멈추고 빠져나오는데 우리가 직접 반복문을 강제로 탈출하게 만들 수 있습니다. 위 예제의 경우는 i가 10보다 커져야 반복을 빠져나오지만, 저기서는 i가 7일 경우에 break문을 만나 바로 반복문을 빠져나오게 됩니다. 간단하죠?


2-2. continue문

이번에는 continue문의 설명을 위해 위의 예제를 다시 한번 수정해보도록 하겠습니다.

>>> i = 0
>>> while i <= 10:
	i += 1
	if i % 2 == 1: continue
	print(i, "번 출력되었습니다.")

2 번 출력되었습니다.
4 번 출력되었습니다.
6 번 출력되었습니다.
8 번 출력되었습니다.
10 번 출력되었습니다.

예제에 사용된 continue문을 만나면, continue문 아래의 문장은 실행하지 않고 반복문의 시작 지점으로 되돌아갑니다. 즉, 반복문의 조건을 검사하는 부분으로 다시 되돌아간다는 말입니다. 직접 코드를 따라가보면, i의 값이 처음에 0이고 반복문 내에서 i가 1이 증가하고 i를 2로 나누어 나머지가 1인지 검사를 하는 코드가 존재합니다. 만약 i를 2로 나눈 뒤의 나머지가 1이면 이것은 홀수라는 의미가 되며, 홀수는 continue문을 만나게 됩니다.


출력된 결과를 보시면 알겠지만, 홀수가 제외되어서 출력되었음을 확인하실 수 있습니다. 홀수는 continue문을 만나 시작 지점으로 되돌아가고 i의 값이 증가하기 때문에 그렇습니다. 반대로 짝수라면 continue문을 만나지 않고, 그 아래의 문장을 계속 수행해나가는 모습을 보실 수 있습니다.


3. for문

마지막으로 for문에 대해서 알아보도록 하겠습니다. 이 for문은 처음에 소개했던대로 튜플, 리스트, 사전, 문자열 등과 같은 순서형 자료가 올 수 있습니다. 우선은 for문의 형태를 보고나서 다시 for문에 대해 알아보도록 하겠습니다.

for 변수 in 순서형 자료:
	문장

이 for문은 순서형 자료(리스트, 튜플 등)의 요소를 하나하나씩 가져와서 변수에 넣습니다. 우선 리스트를 가지고 for문을 이용한 예제를 보도록 하겠습니다.

>>> lst = [1, 3, 5, 7, 9]
>>> for i in lst:
	print(i)
	
1
3
5
7
9

위 예제를 보시면, 리스트 lst의 요소를 하나하나씩 가져와 변수 i에 넣어서 i의 값을 출력하고 있음을 보실 수 있습니다. 그리고 또한 for문에도 역시 break문과 continue문을 사용하실 수 있습니다.

>>> lst = [1, 2, 3, 4, 5, 6, 7, 8]
>>> for i in lst:
	if i % 2 == 1: continue
	if i == 6: break
	print(i, "번 출력되었습니다.")

2 번 출력되었습니다.
4 번 출력되었습니다.

위 예제의 for문 내부 블록을 보시면, i를 2로 나눈 뒤의 나머지가 1인 경우에 시작 지점으로 돌아가고 i가 6과 같으면 반복문을 탈출하게끔 작성해 두었습니다. 1, 3, 5는 첫번째 조건문에 의해 시작 지점으로 돌아가 출력이 되지 않은것이며, 6부터는 두번째 조건문을 만나 반복문을 탈출하여 이후의 문장이 수행되지 않는 것입니다.


3-1. range 함수

여기서 range 함수를 for문에 이용할 수 있는데, range 함수는 숫자의 범위를 가지는 range 객체를 돌려보내며 이를 통하여 for문 내에서 위치를 가지고 요소를 가져오거나 변경할 수 있습니다. 한번 보도록 합시다.

>>> for i in range(10):
	print(i, end=" ")

0 1 2 3 4 5 6 7 8 9 

위 예제에서는 range(10)이 0에서부터 9까지의 범위를 지니는 range 객체를 만들어내며, 이 객체를 가지고 순차적으로 접근하여 값이 i에 담긴 뒤, 저장된 i의 값을 print문으로 출력하는 것입니다. 이를 리스트에서 응용하게 되면 아래의 예제와 같이 사용할 수 있을 것입니다.

>>> lst = [1, 2, 3, 4, 5]
>>> for i in range(len(lst)):
	if i % 2 == 0:
		lst[i] *= 2
	else:
		lst[i] *= -2
	print(lst[i], end=" ")

2 -4 6 -8 10 

위의 예제를 보시면, len 함수를 통해 리스트 lst의 요소 수를 구하고 이 요소 수를 통해 range 함수를 호출하여 요소 수 만큼 반복하게 됩니다. for문의 내부 블록을 보시면 i를 2로 나눈 나머지가 0인 경우, 즉 짝수인 경우에는 i번째 요소의 값에 2를 곱한 값을 저장하고, 홀수인 경우에는 i번째 요소의 값에 -2를 곱한 값을 저장합니다. 결과를 보시면 "2 -4 6 -8 10"과 같은 결과를 보실 수 있습니다. 위의 예제에서는 0~4의 범위를 지닌 range 객체를 만들어 낸것이라고 보면 됩니다. 이해가 잘 되지 않는다면 위 예제를 응용하여 한가지 예를 더 만들어보시면 range 함수가 어떤 녀석인지 이해를 하실 수 있을것 같습니다.


3-2. 반복문의 중첩

반복문의 중첩이란, 반복문 내에 반복문이 들어가는 것으로써 for문 내에 while문이 들어갈수도 있으며, while문 내에 while문이 들어갈 수 있는 등 여러 개의 반복문이 중첩되어 사용될 수 있습니다. 예를 들면, 반복문 중첩을 통해 구구단을 모두 출력할 수 있습니다.

>>> i = 2
>>> while i <= 9:
	j = 1
	while j <= 9:
		print(i, " * ", j, " = ", i * j)
		j += 1
	i += 1

2  *  1  =  2
2  *  2  =  4
...
9  *  8  =  72
9  *  9  =  81

위 코드의 실행 순서를 같이 확인해보도록 할까요? 이해를 돕기 위해, 각 줄에 있는 코드마다 번호를 붙이면 아래와 같습니다. 번호 아래의 변수 i, j의 값은 해당 번호의 문장이 실행되고 나서의 i, j 값을 적은 것입니다. while문의 대략적인 실행 흐름을 살펴보면 '조건식을 검사한다 -> 참이면 내부 블록에 있는 문장을 실행/거짓이면 반복문을 빠져나옴 -> 조건식을 검사한다 -> ...'와 같습니다.

편의를 위해서 내부에 중첩된 while문 영역에 ④번을 붙여뒀지만, 실제로는 아래와 같이 ④번 내부에서 다시 반복문을 돌겠죠? 따로 떼어놓고 각 문장에 번호를 매겨보면 아래와 같은 순서대로 실행이 됨을 알 수 있습니다.

마지막에 1번 문장을 실행하는데, j의 값이 10이므로 'j <= 9'의 조건식이 거짓이 되어 반복문을 탈출하는 것을 볼 수 있습니다. 반복문의 실행 흐름이 어느정도 눈에 보이시나요?


위처럼 while문을 사용할 수 있으나, 아래처럼 for문을 사용할 수도 있습니다.

>>> for i in range(2, 10):
	for j in range(1, 10):
		print(i, " * ", j, " = ", i * j)

2  *  1  =  2
2  *  2  =  4
...
9  *  8  =  72
9  *  9  =  81

참고로 이렇게 두번만 중첩되는게 아니라 여러번 중첩될 수 있다는 사실을 기억해두시기 바랍니다.