파이썬 반복문 for문 while문 기초와 응용 break continue else

파이썬 구문 (statement) 학습 오늘은 반복문에 대해 알아본다. 반복문은 말 그대로 정해진 어떠한 동작을 반복적으로 수행하도록 만드는 명령문이다.

앞서 조건문 if를 공부하면서 학생의 성적, 또는 나이를 입력했을 때 주어진 몇 가지 조건에 따라 분류하고 등급을 매겨서 출력하는 예제까지 만들어보았다. 그런데 만약 그런 작업을 100명, 1000명에 대해서 해야 한다면?

똑같은 조건문을 1000번 반복해서 쓸 수는 없는 노릇이다. 이럴때 바로 반복문을 사용해서 처리할 수 있다. 반복문에는 for, while 두 가지가 있다.

for문의 기본 문법구조

✔️ 파이썬의 기본적인 반복문

✔️ 범위를 지정하여 반복명령 수행

✔️ 변수에 지정한 범위의 내용을 하나씩 순차적으로 대입

for문을 이용해 어떻게 반복 명령을 수행하는지 살펴보자. 직접 보고 만들어보고 오류도 나보고 수정해가면서 느는 수밖에 없는 것 같다. 프로그래밍 공부라는 건.

## 코드 1
for i in ["Korea", "USA", "China", "Japan"]:
    print(i)

## 결과 1
Korea
USA
China
Japan


## 코드 2
fruits = ["banana", "grape", "apple"]
for i in fruits:
    print(i)

## 결과 2
banana
grape
apple

이런 식으로

for 변수 in (범위) :

형태로 작성해준다.

[~~] 괄호 형태로 여러가지를 넣어준 것은 일전에 공부했던 데이터 타입 중 하나인 리스트형이다. 

코드1 처럼 리스트에 데이터들을 넣어놓고 변수에 하나씩 대입하면서 수행문을 반복 하라고 할 수도 있고, 코드2 처럼 리스트를 어떠한 변수명으로 만들어 준 뒤, 그 변수명을 for문에 가져와서 사용할 수도 있다.

리스트로 대량의 데이터를 입력하고 그것을 여러번 사용해야 한다면 변수명으로 지정하고 쓰는게 편할 것이다.

다음 예제는 리스트는 지정했는데 실제로 다른걸 출력하는 반복문이다.

출력예제

이렇게 하면 리스트에 뭐가 들었는지는 의미가 없고 4개가 들어있으니 그저 print(“hello”) 를 4번 반복 수행하는 셈이 된다. 

반복문을 이용한 출력예제

또 반복 범위에 문자열을 넣어주면 위와 같이 글자 하나하나를 순차적으로 변수로 불러오게 된다.

range로 범위 지정하기

반복 횟수만 지정해주고 싶을 때는 리스트에 숫자를 넣어주거나, range 함수를 이용해서 반복횟수를 지정해 줄 수 있다.

range(시작, 끝+1, 간격)

형태로 입력하는데, 시작을 입력하지 않으면 기본적으로 0부터시작, 그리고 간격은 입력하지 않으면 기본값이 1로 지정된다.

## 코드1
for i in range(6):
    print(i,end=" ")

## 결과1
0 1 2 3 4 5 


## 코드2
for i in range(1,6):
    print(i,end=" ")

## 결과2
1 2 3 4 5 


## 코드3
for i in range(1,10,2):
    print(i,end=" ")

## 결과3
1 3 5 7 9 

Note that range(6) is not the values of 0 to 6, but the values 0 to 5.

주의 : range(6)은 0에서 6까지라는게 아니고, 그 값은 0에서 5까지이다.

range(6) → 시작 0, 끝 5, 간격 1

range(1,6) → 시작 1, 끝 5, 간격 1

range(1,10,2) → 시작 1, 끝 9, 간격 2

이런 의미를 갖는다는 것을 숙지하자. 파이썬에서 왠만하면 다 시작은 0이고 끝값은 써있는거보다 하나 앞까지만을 범위로 포함한다. (컴퓨터가 이진수이기 때문에 효율을 위해 프로그래밍 언어들이 그런식으로 되었다고 한다.)

## 코드
for i in range(10,3,-1):
    print(i,end=" ")

## 결과
10 9 8 7 6 5 4    

range 에서 간격을 마이너스 (-)로 하면 역순으로 할 수도 있다. 이 때는 끝을 3이라고 지정했는데 3보다 전인 4에서 끝나는 것을 알 수 있다. 즉 끝지점을 3이라고 한다고 무조건 2까지 되는게 아니라, 방향에 따라 달라지는 것이다.

range함수 예시

range 함수를 통해 나오는 값들을 이렇게 list로 감싸서 하나의 자료형으로 만든 뒤 활용할 수도 있다.

응용 : else, break, continue, pass

아래 예제를 보고 for문에 else, break를 어떻게 적용하는지 살펴보자.

## 코드1
for x in range(6):
  print(x)
else:
  print("finished!")

## 결과1
0
1
2
3
4
5
finished!


## 코드2
for x in range(6):
  if x == 3: break
  print(x)
else:
  print("finished!")

## 결과2
0
1
2

코드1에서 보면 range(6)까지 for문을 모두 수행한 후 else문에 있는 문장이 출력되었다. if문에서는 조건에 해당하지 않았을 경우 else로 넘어갔지만, for문에서는 수행이 모두 완료되었을 경우에 else가 출력됨을 유의하자.

코드2를 보면 중간에 if문과 break를 사용하여 반복루프를 중단시켰다. x가 3이 되었을 때 break하고 for문을 빠져나가라는 의미이다. 따라서 print(3)이 수행되기 전에 break에 의해 for문을 빠져나왔고, 결과는 0, 1, 2만 출력되고 끝났다.

여기서는 else문이 수행되지 않는다. for문이 모두 완료되었을 경우에만 else 구문의 내용을 수행하고, 중간에 break된 경우에는 else문의 내용까지도 스킵한다. for-else 까지가 한 덩어리인데 break 했으니 통째로 빠져나간다고 보면 된다.

통째로 빠져나가지 않고 특정 경우만 건너뛸 수는 없을까?

## 코드
for x in range(6):
  if x == 3: continue
  print(x)
else:
  print("finished!")

## 결과
0
1
2
4
5
finished!

이렇게 break 대신 continue를 사용하면 된다. 이 경우 x가 3일 때 continue를 받아서 다시 for문으로 돌아가서 반복한다. 결과를 보면 3일 때만 print가 진행되지 않았음을 알 수 있다. 정상적으로 루프가 진행 완료되었기에 마지막에 else 구문도 수행이 되었다.

for문 들여쓰기 블락

for문은 반드시 들여쓰기 문장을 포함한 블락으로 구성되어야 한다. 그렇지 않을 시 위와 같이 에러가 난다. 에러 내용도 indented block 있어야된다고 나온다.

for x in range(6):
    pass

이럴 때 위와 같이 들여쓰기 문장으로 pass 를 써주면 아무 출력 결과물 없지만 에러나는 것을 방지하고 넘길 수 있다. 지금 이걸 써야되는 상황같은건 없으니까 그냥 이런게 있구나 정도로만….

nested loop (중첩루프)

중첩루프는 for문 안에 또 다른 for문을 넣어서 이중 반복문 구조를 만드는 것이다. 예를 들면 1,2,3이 있고 a,b,c가 있는데 1a 1b 1c 이렇게 반복하고 그 다음에 2a 2b 2c … 이런 식으로 하부 구조는 상위 반복문의 요소 하나마다 반복이 된다.

이걸 머에다 쓰나❓❓ 중첩 루프를 이용해서 구구단을 출력하도록 만들 수 있다.

구구단 만들기 예시

먼저 range에서 x에 1이 할당되고, 그 상태에서 y 1~9까지 한번씩 print문을 수행한다. 끝나면 y에 대한 for문이 끝나고 상부 구조로 빠져나가서 x가 2가 된다. 이런식으로 x가 1~9가 되는 동안 각각에 대해 y는 1~9를 반복하니 구구단을 만들 수 있다.

while문의 기본 문법구조

이제 파이썬의 또 다른 반복문인 while문에 대해 공부해보자. for문과 마찬가지로 구구절절 설명보다는 직접 이런저런 예제를 보면서 어떻게 입력해야 하는지 감을 잡는게 빠르다.

## 코드 
i=1
while i<10:
    print(i,end=" ")
    i+=1

## 결과
1 2 3 4 5 6 7 8 9

while 반복문은 조건문의 특징도 갖고 있다. 어떠한 조건에 해당하는지 비교하고 해당하면 루프를 수행, 조건을 벗어나면 반복을 멈추고 빠져나오게 된다.

위 예시에서 i에 초기값 1을 부여하고, i가 10미만인 동안 while문이 반복 수행되도록 하였다. 수행문은 i값을 출력해 준 뒤 i에 1을 더하는 것이다.

1을 더하지 않으면 어떤일이 생길까?

무한루프 걸리는 while문 예시

끄아악~ 루프가 무한하게 수행되면서 멈추질 않는다. 이렇게 루프가 멈추지 않게 만든것은 프로그램을 ‘잘못짠’ 것이다. VS Code의 주피터 결과화면 위에 나온 메세지 부분을 클릭해보면

주피터 출력설정

이렇게 세팅에서 출력설정을 할 수 있다. 아마 코딩을 잘못한 경우 무한루프에 의해 과도한 컴퓨터 자원이 점유되거나 다운되는 것을 방지하기 위함일 것이다.

Note: remember to increment i, or else the loop will continue forever.

주의 : i를 증가시키는걸 잊지 말자, 그렇지 않으면 루프가 무한 반복된다.

for문 vs while문

파이썬 반복문의 대표적인 두 가지 구문인 for while 에 대해 살펴보았는데, 어떨때 for를 쓰고 어떨 때 while을 쓸까? 

반복하는 횟수가 정해져 있는 경우, 명확한 경우에 for구문을 쓴다. 그리고 얼마나 반복 수행해야 할 지 모를 때, 특정한 조건에 도달할때까지 계속해 이런 명령을 하고 싶을 때 while문을 사용한다.

응용 : break, continue, else

while문에서도 for문과 마찬가지로 break, continue, else 등을 추가할 수 있다. 예제를 통해 살펴보자.

## break 사용 코드
i = 1
while i < 6:
  print(i)
  if i == 3:
    break
  i += 1

## break 사용 결과
1
2
3

break 사용시 특정 조건 도달하면 빠져나가는 것은 for문과 같다.

## continue 사용 코드
i = 0
while i < 6:
  i += 1
  if i == 3:
    continue
  print(i)

## continue 사용 결과
1
2
4
5
6

continue 사용시 해당 회차 반복을 그만하고 다시 while문을 수행한다. 위 예시에서 continue 구문을 사용한 경우 만약 i+=1을 아래에 넣어두었다면 무한루프 함정에 빠졌을 것이다. i가 증가하지 않고 계속 continue로 돌아갈 테니.

## else 사용 코드
i = 1
while i < 6:
  print(i)
  i += 1
else:
  print("i is no longer less than 6")

## else 사용 결과
1
2
3
4
5
i is no longer less than 6

else또한 마찬가지로 반복문이 완료되면 마지막에 한번 수행해준다. for문 때와 마찬가지로 break를 통해서 빠져나왔을 경우 수행되지 않는다.

여기까지 파이썬의 반복문인 for문 while문에 대해 알아보았고, 이제 실제로 좀 더 복잡한 예제 문제들을 보며 직접 코드를 만들어보고 부딪혀가며 체득하자.

실습 : 구구단계산기

위에서 for문 설명에 구구단 출력하는 간단한 코드는 이미 써놓았는데, 여기서는 숫자를 입력받아서 해당 단의 계산만 나오도록 하는 방법을 해보자.

숫자를 입력받고, 1~9 범위일 경우에만 구구단을 출력하도록

number=int(input("구구단 몇 단을 계산할까요?"))
if number<1 or number>9:
    print("1에서 9 사이를 입력해주세요")
else:
    print("구구단",number,"단입니다.")
    for i in range(1,10):
        print(number,"X",i,'=',number*i)

이렇게 먼저 입력값을 int 형태로 변수에 저장하고, 변수가 1에서 9를 벗어났다면 print문으로 출력하고 종료, 그렇지 않으면 else문으로 들어가서 for 반복문을 수행하게 된다.

구구단 출력기 예시

결과화면. 처음에 입력값 받을 때 변수에 int 형태로 저장하는 것에 주의하자. 그렇지 않으면 number가 문자열 형태가 되어서 마지막에 출력할 때 9, 99, 999, … 이런 식으로 나오게 된다.

실습 : 2진수 변환기

10진수 숫자를 입력받아서 2진수로 바꿔주는 파이썬 코드를 만들어보자.

2진수 변환개념

일단 10진수를 2진수로 어떻게 바꾸는지 알아야 코드를 만들던 말던 할테니…. 위와 같이 10진수를 2로 계속 나누면서 0또는 1로 나올 나머지만 순서대로 적어준 뒤 밑에서부터 역순으로 읽어주면 2진수 변환이 된다.

입력받은 숫자를 계속 2로 나누면서 나머지 값을 문자형으로 변환해서 차례로 이어주는 식으로 만들면 되겠다.

## 변수 정의
## decimal : 십진 수 입력값
## binary : 이진 수 변환값
## remainder : 나머지


## 코드
decimal=int(input("10진수 값을 입력하세요 : "))
binary=''
while decimal>0:
    remainder=decimal % 2
    decimal=decimal // 2
    binary=str(remainder)+binary
print(binary)

❄️️️️️decimal 변수에 정수 형태로 10진수 입력값을 받고, binary는 초기에 비어있는 문자열 변수이다. 

❄️️️️️decimal이 0 이상이라면 반복문을 수행한다.

❄️️️️️devimal을 2로 나누고 그 나머지를 remainder에 저장

❄️️️️️decimal값은 2로 나눈 몫 값응로 치환한다.

❄️️️️️binary 변수의 앞부분에 나머지 값 remainder를 문자열 형태로 바꿔서 붙여준다. 

2진수 변환기 코드 예시

결과는 이렇게 17을 입력했을 때 10001로 위의 스크린샷 이미지와 동일하게 나옴을 확인하였다.