파이썬 반복문 이해하기

파이썬 반복문 이해하기

컴퓨터의 위대한 기능 중 하나가 같은 것을 계속 반복할 수 있다는 점이다. 심지어 이런 업무에 있어 불평하거나 지치지도 않는다.

루프(loop)란 특정 횟수나 조건이 만족했을 때 까지 계속해서 반복되는 코드 블럭이다. 파이썬에는 두 가지 종류의 루프가 존재하는데, 바로 while 루프와 for 루프이다. 두 가지 반복문을 어떻게 사용하는지 들여다보자.


while 반복문(while Loop)

while 반복문은 조건이 참(true)일 동안 코드의 섹션을 계속해서 반복한다.

모든 while 반복문에는 두 부분으로 나뉘어져있다.
  1. while문은 while 키워드로 시작하며, 그 뒤에 테스트 조건이 오고, 마지막으로 콜론(:)으로 끝난다.
  2. 반복문의 본문(body)은 각 단계에서 반복되는 코드가 포함되어 있다. 각 줄은 네 칸 들여쓰기를 한다.

while 반복문이 실행되면, 파이썬은 테스트 조건을 판단해서 조건이 참(true)인지 거짓(false)인지 결정한다. 만약 테스트 조건이 참이면, 반복문의 본문에 있는 코드가 실행된다. 그렇지 않다면, 본문 안에 코드는 생략되고 프로그램의 나머지 부분이 실행된다.

만약 테스트 조건이 참이여서 본문 안의 반복문이 실행되고, 파이썬이 본문 끝까지 도달했다면, 다시 while문으로 돌아가 테스트 조건을 평가한다. 만약 테스트 조건이 여전히 참이라면, 반복문의 본문이 다시 실행된다. 만약 거짓이라면, 본문은 생략된다.

>>> n = 1
>>> while n < 5:
... 	print(n)
... 	n = n + 1
...
1
2
3
4

코드를 살펴보면, 첫 번째로 1이 변수 n에 할당된다. 그리고 while 반복문이 n의 값이 5보다 작은지 체크하는 테스트 조건 n < 5와 같이 생성된다. 만약 n이 5보다 작으면, 반복문의 본문이 실행된다. 반복문의 본문 안에는 두 줄의 코드가 존재하는데, 첫 번째 줄은 n의 값이 화면에 출력되고, 두 번째 줄에서는 n이 1씩 증가한다.

반복문은 다음 이미지처럼 총 다섯 단계로 진행된다.

Image from Python Basics

만약 반복문을 조심스럽게 작성하지 않으면, 의도치 않게 무한 반복문(infinite loop)을 생성할 수도 있다. 무한 반복문은 테스트 조건이 항상 참일 때 발생한다. 왜냐면 테스트 조건이 계속 만족되기 때문에, 계속하여 반복되고 반복문은 끝나지 않는 것이다.

아래 예제는 이전 예제와 다르게 테스트 조건을 만족 후 변수 n의 값이 1씩 증가하지 않아 계속해서 n < 5 조건을 충족하게 된다. 즉, n의 값이 1로써, 무한 반복하게 된다.

>>> n = 1
>>> while n < 5:
... 	print(n)
...

for 반복문(for loop)

for 반복문은 아이템의 집합의 각 항목에 대해 코드 섹션을 한 번씩 실행한다. 반복문 안의 코드가 반복되는 횟수는 아이템의 수의 따라 결정된다.

for 반복문도 while 반복문처럼 두 메인 파트로 나뉘어진다.
  1. for문은 for 키워드로 시작하며, 그 뒤에 멤버십 표현식(membership expression)이 따라오고, 마지막에는 콜론(:)으로 끝난다.
  2. 반복문의 본문(body)은 각 단계에서 반복되는 코드가 포함되어 있다. 각 줄은 네 칸 들여쓰기를 한다

다음의 for 반복문은 문자열 파이썬의 각 문자를 출력하는 반복문이다.

for letter in "Python":
	print(letter)

이 예제에서 for문은 for letter in "Python"이고, 멤버십 표현식은 letter in "Python"이다.

반복문의 각 단계에서, 변수 letter에 문자열 "Python"의 각 문자가 할당되고 문자의 값이 인쇄된다. 반복문은 문자열 "Python"의 각 문자에 대해 한 번씩 실행되므로, 반복문의 본문은 총 여섯 번 실행된다.

반복문은 다음 이미지처럼 총 여섯 단계로 실행된다.

Image from Python Basics

작성한 for 반복문을 while 반복문으로 작성하면 훨씬 더 복잡해지는 것을 확인할 수 있다.

word = "Python"
index = 0

while index < len(word):
	print(word[index])
	index = index + 1

for 반복문이 while 반복문보다 덜 복잡한 것 뿐만 아니라, 코드 자체가 훨씬 더 자연스럽게 보여진다. 마치 실제로 말을 반복할 때 처럼 말이다.

파이썬을 사용하다보면 특정 코드를 보고 "파이써닉(Pythonic)"하다고 표현하는 것을 가끔 볼 수 있다. 파이써닉이란 용어는 보통 명확하고, 간결하며, 그리고 파이썬의 내장 기능을 잘 사용하여 이점이 있는 코드를 뜻한다.

반복문에 대입해서, while 반복문을 사용하는 것 보다, 아이템의 집합을 반복하는 for 반복문을 사용하는 것이 더 파이써닉하다고 할 수 있다.

파이썬에서는 숫자의 범위만큼을 생산하는 range()라는 내장 함수를 제공해, 숫자의 범위만큼 반복할 수 있도록 도와준다. 예를 들어, range(3)은 0부터 시작하는 정수의 범위를 반환하지만, 3을 포함하지는 않는다. range(3)의 범위는 숫자 0, 1, 그리고 2이다.

range() 함수는 range(n)처럼 n의 수만큼 반복을 실행하기 위해 양수인 숫자와 함께 사용할 수 있다. 예를 들어, 다음의 for 반복문은 문자열 "Python"을 세 번 출력한다.

for n in range(3):
	print("Python")

더 나아가서 range() 함수에 시작점을 지정해 줄 수도 있다. 예를 들어, range(1, 5)는 숫자 1, 2, 3, 4의 범위이다. 첫 번째 인수가 시작점이고, 두 번째 인수가 종료점이다(종료점은 범위에 포함되지 않는다).

range() 함수 안에 시작점과 종료점을 사용하여 다음과 같은 예제를 만들 수 있다. 다음 for 반복문은 10을 시작점으로 19까지의 모든 숫자를 제곱해 출력한다.

for n in range(10, 20):
	print(n * n)

중첩 반복문(Nested Loops)

반복문 안에서 들여쓰기만 정확히 된다면, 반복문 안에 다른 반복문을 삽입할 수도 있다.

for n in range(1, 4):
	for j in range(4, 7):
		print(f"n = {n} and j = {j}")

위 중첩 반복문의 단계를 살펴보자. 먼저 파이썬이 첫 번째 for 반복문 본문에 들어가면, 값 1이 변수 n할당된다. 그리고 본문의 두번째 for 반복문이 실행되고, 값 4가 j할당된다. 제일 먼저 출력되는 것은 n=1j=4이다.

print() 함수가 실행되고나면, 파이썬은 안 쪽의 for 반복문으로 돌아가, j에 값 5를 할당하고 다시 n=1j=5를 출력한다. 파이썬은 안에 중첩된 for 반복문의 실행이 끝나지 않았으므로, 바깥 for 반복문을 실행하지 않는다. j가 6이 되면 안 쪽 반복은 끝이나고, 바깥쪽 for 문으로 돌아가게된다.

안쪽 반복문이 종료되고 나면, 바깥쪽 변수 n에 값 2가 할당이 되고, 위 단계처럼 계속하여 범위가 끝날 때 까지 반복된다. 즉, 예제의 중첩 반복문의 최종 출력은 다음과 같다.

n = 1 and j = 4
n = 1 and j = 5
n = 1 and j = 6
n = 2 and j = 4
n = 2 and j = 5
n = 2 and j = 6
n = 3 and j = 4
n = 3 and j = 5
n = 3 and j = 6

이처럼 또 다른 반복문 안의 반복문을 중첩 반복문(nested loop)이라고 부른다. for 반복문 안에 while 반복문을 사용하는 것도 가능하고, 그 반대로도 사용이 가능하다.

단일 for 반복문과 비교했을 때, 중첩 반복문을  사용하면, 보이는 것처럼 코드 안에 더 많은 단계가 생기고, 코드의 복잡성을 증가시킨다.

중첩 반복문을 꼭 사용해야 할 상황에는 사용해야겠지만, 과한 중첩 반복문 사용은 프로그램의 퍼포먼스에 안 좋은 영향을 끼칠 수 있다.

Reference