본문 바로가기
카테고리 없음

[Python] 기본문법 - 반복문 (for, while)

by A6K 2022. 10. 27.

조건문과 함께 프로그래밍 언어의 기본 블럭을 구성하는게 반복문이다. 파이썬을 비롯한 다양한 프로그래밍 언어는 반복문을 지원하여 단순 반복적인 동작을 간단하게 표현할 수 있게 해준다.

반복문

예를들어보자. 1부터 1000까지 숫자를 화면에 출력하는 간단한 작업을 파이썬으로 작성한다고 해보자. 그러면 가장 기초적으로는 1부터 1000까지 숫자를 print() 함수로 출력하면 된다.

print("1\n")
print("2\n")
print("3\n")

...

print("998\n")
print("999\n")
print("1000\n")

좋다. 이제 1부터 10000까지 숫자를 화면에 찍어보자.. print('1\n').. 이런거보다 반복문을 사용하면 다음과 같이 간단하게 표현할 수 있다.

for i in range(1, 10001):
  print(i)

10000개의 라인을 사용하지 않아도 1부터 10000까지의 숫자를 화면에 출력할 수 있다. 이렇듯 반복되는 규칙이 있다면 반복문을 이용해서 좀 더 간결하게 코드를 작성할 수 있다.

for 문

파이썬에서 제공하는 반복문에는 for 문이 있다. for문의 구조는 다음과 같다.

for [변수] in [리스트 or 문자열 or 튜플 or 기타]:
  statements

어떤 자료구조에 들어있는 요소하나하나를 선택해서 변수에 할당한 다음 반복적으로 명령어를 수행한다. for 문의 in 키워드 뒤에 문자열이나 리스트, 튜플 같은 자료구조가 올 수 있다. 이 자료구조에 있는 요소를 하나씩 변수에 넣어 주고 statement를 실행한다.

예를 들어

my_list = ['one', 'two', 'three']

for i in my_list:
  print(i)
  
  # one
  # two
  # three

my_list에 문자열 리스트를 할당하고 for문에 사용했다. 리스트에 담겨 있는 요소들을 하나씩 i 변수에 할당하고 print(i)를 수행하므로 one, two, three 가 순서대로 출력된다.

혹은 튜플을 이용해서 다음과 같이 사용할 수도 있다.

list_of_tuple = [(1, 3), (2, 4), (3, 5)]
for (first, second) in list_of_tuple:
  print(first + second)
  
# 4
# 6
# 8

리스트에 있는 튜플이 각각 (first, second)로 할당되었고, 이 두 값을 더한 값을 출력하는 예제를 작성했다.

while 문

for 문과 함께 파이썬은 while 문이라는 반복문을 제공한다. while 문의 구조는 다음과 같다.

while [조건문]:
  statements

while 문은 함께 작성된 조건문이 참인 동안 계속 반복된다. 여러번 반복되다가 조건문이 거짓이 된다면 반복을 종료하게 된다. 예를 들어보자.

num = 10

while num > 0:
  print(num)
  num = num - 1

# 10
# 9
# 8
# 7
# 6
# 5
# 4
# 3
# 2
# 1

num 이라는 변수에 10을 할당하고, while 문으로 들어갔다. num이라는 값이 아직은 0보다 크니까  while 문의 body를 실행한다. while 문의 body에서는 num 변수를 출력하고 1씩 감소시킨다. while 문이 실행되면서 num 변수의 값은 9, 8, 7, ... 로 감소하다가 0이 되면서 반복문이 종료된다.

좀 더 응용을 해서 조건문과 함께 사용해 1부터 10까지의 숫자 중에 짝수만 출력하는 코드를 작성해 볼 수 있다.

num = 10

while num > 0:
    if num % 2 == 0:
        print(num)
    
    num = num - 1
  
# 10
# 8
# 6
# 4
# 2

무한루프

반복문의 조건을 의도적으로 혹은 잘 못 작성한 경우 반복문이 무한히 반복되는 경우가 있다. 이런 경우를 무한루프라고 한다. 예를 들어보자.

num = 1
while num > 0:
  print(num)
  num = num + 1

이런 코드를 생각해보자.  num 변수에 1을 할당하고 반복문을 시작한다. while 반복문의 조건은 num이 0보다 큰 경우이다. 그리고 반복문의 Body에서는 num 변수를 출력하고, num 변수를 1 증가시킨다. 그리고 그 다음번 반복문을 실행한다.

문제는 num 변수는 결코 0보다 같거나 작아질 수 없다는 것이다. num은 1, 2, 3, ... 이렇게 영원히 증가한다. 이 코드를 실행시켜보면 숫자가 영원히 증가하는 것을 볼 수 있다. 종료하려면 개발환경의 Stop 버튼을 누르거나 터미널 환경인 경우 [Ctrl] + [C] 버튼을 눌러서 인터럽트를 걸어줘야한다.

그러면 무한루프는 무조건 버그인가? 그렇지는 않다. 예를 들어 서버 프로그램의 경우 클라이언트의 요청을 별도의 셧다운이 없는 경우 영원히 기다렸다가 처리해줘야한다.

while True:
  wait_client()
  process_client_request()

이런식으로 반복문의 조건은 무조건 True로 설정해두고 무한히 반복적으로 클라이언트의 요청을 처리하는 경우가 필요할 수 있다. 이럴 때 무한루프를 사용하게 된다.

중첩된 반복문

반복문은 여러개를 겹쳐서 사용할 수도 있다. 예를 들어 구구단을 출력하는 프로그램을 작성해보자. 

for i in range(2, 10):
  for j in range(1, 10):
    print('{0} x {1} = {2}'.format(i, j, i * j))
    
    
# 2 x 1 = 2
# 2 x 2 = 4
# 2 x 3 = 6
...

반복문 안에 반복문이 들어가서 동작한다. 동작하는 원리는 반복문 하나를 사용했을 때의 개념을 두번 적용한 것이다. for i in range(2, 10) 반복문의 Body로 for j in range(1, 1)이 실행된다. 즉, for j in range(1, 10) 반복문이 2부터 9까지 (10은 포함안됨) 반복해서 실행된다. 각 반복마다 for j in range(1, 10)이  실행되며 그 j를 사용하는 for문의 Body 부분이 각각 9번 실행된다.

break

반복문과 함께 사용할 수 있는 키워드로 break가 있다. 반복문의 body를 실행하다가 break 키워드를 만나면 반복문의 실행을 종료한다. (for문과 while문 모두와 함께 사용할 수 있다)

사용자의 입력을 받아서 그대로 화면에 출력해주는 프로그램을 작성해보자.

while True:
  user_input = input()
  if user_input == 'exit':
    break
    
  print(user_input)
  
  
# a
# a
# b
# b
# c
# c
# word
# word
# click
# click
# exit

위에서 봤던 무한루프를 작성했다. 그리고 input() 함수를 이용해 사용자의 입력을 받아 user_input 변수에 할당하고 화면에 출력했다. 사용자가 'exit'를 입력하면 화면에 출력하지 말고 반복문을 벗어나 프로그램을 종료한다.

반복문에 사용한 조건을 검사하지 않아도 break 구문을 만나면 바로 직전 반복문을 종료하게 된다.

continue

반복문과 함께 사용할 수 있는 또 다른 키워드로 continue가 있다. 반복문의 body를 실행하다가 continue 키워드를 만나게 되면 다음 반복으로 바로 넘어간다.

예를 들어 다음 코드는 1부터 10사이의 홀수 숫자만 출력한다.

for i in range(1, 10):
  if i % 2 == 0:
    continue
  print(i)
  
# 1
# 3
# 5
# 7
# 9

1부터 9까지 숫자를 변수 i에 할당하고 반복문의 body 부분을 실행한다. 반복문의 body 부분에서 i 변수의 값을 2로 나눈 나머지를 확인해서 0인 경우.. 즉 짝수인 경우 continue 를 만나게 되고, Body의 나머지를 실행하지 않고 다음번 반복으로 넘어간다. 만약 홀수인 경우 조건문의 조건에 걸리지 않으므로 continue를 만나지 않게 되어 print() 함수를 실행한다.

리스트 내포(List comprehension)

좀 더 고급 반복문인 리스트 내포(List Comprehension)에 대해서 알아보자. 다음 코드를 생각해보자.

values = [1, 2, 3, 4, 5]
result = []

for i in values:
  result.append(i * 2)

print(result)

# [2, 4, 6, 8, 10]

1부터 5까지 숫자를 담고 있는 values라는 리스트가 있다. 이 리스트의 항목을 하나씩 돌면서 2를 곱해 새로운 리스트로 만드는 반복문이다. 요약하면 리스트에 있는 모든 항목에 어떤 작업을 하고 싶은 경우다.

파이썬으로 코드를 작성할 때, 이런 경우가 꽤나 많다. 파이썬은 리스트 내포를 이용해서 좀 더 간결하게 코드를 작성할 수 있게 해준다.

values = [1, 2, 3, 4, 5]
result = [i * 2 for i in values]
print(result)

# [2, 4, 6, 8, 10]

만약 1부터 10까지의 숫자 중 홀수들만 뽑아서 10을 곱한 결과를 얻고 싶다면 다음과 같이 작성하면 된다.

result = [i * 2 for i in range(1, 11) if i % 2 == 1]
print(result)

# [2, 6, 10, 14, 18]

리스트 내포는 다음과 같은 문법을 사용한다.

[표현식 for 항목 in 반복가능한 객체 if 조건문]

뒤쪽에 있는 조건문은 선택사항으로 필요한 경우만 써주면 된다.

리스트 내포는 중첩된 반복문도 가능하다.

[표현식 for 항목1 in 반복가능한 객체1 if 조건문1
        for 항목2 in 반복가능한 객체2 if 조건문2
        for 항목3 in 반복가능한 객체3 if 조건문3
        ... ]

예를 들어 구구단 숫자들을 차례로 담을 수 있다.

values = [i * j for i in range(2, 10)
                for j in range(1, 10)]
                
print(values)

# [2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]

for문 vs while 문

for 문과 while 문은 각각 쓰면 좋은 경우가 있다.

for 문은 대부분 자료구조의 각 항목들을 순회하면서 뭔가를 하고 싶은 경우에 사용한다. while 문은 무한 루프를 돌리거나 특정 조건이 만족할 때까지 반복해야하는 경우에 많이 사용한다.

어떤 상황에서 어떤 구문을 사용할지 정해져있는 것은 아니고 프로그래머가 스스로 판단해서 사용하면 된다.


 

파이썬 스크립트 작성에 도움되는 글 모음

파이썬으로 프로그램을 작성할 때 도움되는 글들을 모아본다. 개발환경 [Python] macOS에 파이참 설치 [Python] 파이참 깃허브 연동 [Python] 파이썬 PIP란? [Python] VSCode를 이용한 개발환경 [Python] python3..

hbase.tistory.com

 

댓글