코린이의 소소한 공부노트

반복문 - while, for 본문

Python

반복문 - while, for

무지맘 2021. 5. 21. 21:00

코드를 짜다보면 반복적으로 해야 할 일들이 꽤 많이 생기게 된다. 예를 들면..

# 노란색 펜이 어디있더라..?
pencil_case = ['파란색 펜', '까만색 펜', '지우개', '자', '노란색 펜', '빨간색 펜', '샤프']

if pencil_case[0] == '노란색 펜':
    print('0번째에 있었네!')
elif pencil_case[1] == '노란색 펜':
    print('1번째에 있었네!')

# .. 중략 ..

elif pencil_case[5] == '노란색 펜':
    print('5번째에 있었네!')
else:
    print('...마지막에 있었네..')

사람 편하자고 하는게 코딩인데, 이렇게 불편하게 쓸 수는 없다!! 위의 예시의 경우는 오늘 볼 while(와일)문 또는 for(포)문으로 저것보다 간결하게 쓸 수 있다.

 

이번 글에서는

1. 반복문이란 무엇인지 알아보고

2. while 뜯어보고

3. for도 뜯어보려 한다. 그리고

4. 같은 문제를 while과 for로 어떻게 풀지 간단한 예시를 들어보도록 하겠다.


1. 반복문(loop, 루프)이란 무엇인가?


반복문은

1) 매크로처럼 여러 데이터에 대해서 같은 일을 계속하게 만드는 도구이다.

2) 코딩을 하면서 많이 사용하는 구문 중 하나. 숙지하는 것이 큰 도움이 된다.

3) while문과 for문이 있다. 그 중 while문은 특정 조건을 만족할 때만 반복하고싶을 때 사용할 수 있고, for문은 컬렉션 타입의 아이템을 하나씩 순회하면서 반복적인 일을 하고 싶을 때 사용할 수 있다.

4) 여러개를 중첩해서 사용할 수 있다. 즉, 아래와 같은 코드를 작성할 수 있다는 뜻이다.

반복문 1 시작:
    반복문 2 시작:
        반복문 3 시작:
        ...
        반복문 3 끝
    반복문 2 끝
반복문 1 끝

2. while 뜯어보기


while문은

1) 조건이 True일 경우에만 while 코드 블록을 수행한다. 코드 블록 구분은 들여 쓰기로 한다.

2) 조건이 False가 되면 코드블럭을 수행하지 않고 다음 코드를 실행한다.

# while문의 생김새

while 조건:           # 조건을 따져서
    while block start # 참이면 코드 블록 수행
    ...
    while block end

next code...          # 거짓이면 다음 코드 수행

3) 조건이 False가 되는 경우가 없으면 수행을 멈추지 않는다. 이를 무한루프라고 하고, 내가 무한루프를 노린 것이 아닌 이상 무한루프를 멈추려면 커널 종료, 프로그램 종료와 같은 일을 해야 한다. 무한루프 작성은 지양한다.

while True:
    print('안끝나지롱')

>> 안끝나지롱
>> 안끝나지롱
>> 안끝나지롱
>> 안끝나지롱
...

4) while문은 코드블럭을 다 수행하고 조건을 따진다. 만약 코드 블록 수행 중에 loop를 빠져나가고 싶다면 break(브레이크)를 사용하면 된다. 여기서 while 조건부분에 쓰인 len 함수는 컬렉션 타입의 길이를 계산해주는 내장함수(import없이 쓸 수 있는 함수)이다.

# 엄마가 대충 읊어준 음식들
mom_says = ['김치만두', '쌀국수', '크로플', '냉묵밥', '아아']
# 사실 울 마망은 답정너
answer = '크로플'

i = 0 # 리스트의 인덱스

while i < len(mom_says):
    if mom_says[i] == answer:        
        break
    print('{}? 글쎄..?'.format(mom_says[i]))
    i += 1 # 이게 없으면 무한루프

print('그래 그거 먹자! {}!'.format(mom_says[i]))

>> 김치만두? 글쎄..?
>> 쌀국수? 글쎄..?
>> 그래 그거 먹자! 크로플!

5) 만약 break처럼 중단해서 빠져나오는게 아니라 코드 수행만 스킵하고 다시 loop의 처음으로 돌아가고 싶다면 continue(컨티뉴)를 사용하면 된다. 위 예제에서 break만 continue로 바꿔보겠다. 단순히 break만 continue로 바꾸면 i값이 바뀌지 않아서 무한루프에 빠지므로 코드를 살짝 조정했다.

# 엄마가 대충 읊어준 음식들
mom_says = ['김치만두', '쌀국수', '크로플', '냉묵밥', '아아']
# 사실 울 마망은 답정너
answer = '크로플'

i = 0 # 리스트의 인덱스

while i < len(mom_says):    
    if mom_says[i] == answer:
        zzin = i # 크로플 인덱스 저장
        i += 1 # 이게 없으면 무한루프
        continue
    print('{}? 글쎄..?'.format(mom_says[i]))
    i += 1 # 이게 없으면 무한루프

print('그래 그거 먹자! {}!'.format(mom_says[zzin]))

>> 김치만두? 글쎄..?
>> 쌀국수? 글쎄..?
>> 냉묵밥? 글쎄..?
>> 아아? 글쎄..?
>> 그래 그거 먹자! 크로플!

 

 

크로플은 if문을 참으로 만들기 때문에 continue를 만나서 다시 while 처음으로 돌아갔고, 그 덕에 글쎄..? 출력에 크로플은 빠질 수 있었다. 아 쫀쫀한 바닐라 아이스크림이 얹어진 크로플 먹고 싶다..


3. for 뜯어보기


for는

1) 리스트, 튜플과 같은 컬렉션 타입이나 문자열 같은 순회 가능한(iterable) 객체를 순회하면서 반복적인 일을 할 때 쓴다.

# for문의 생김새

for 변수 in 순회가능한객체:
    for block start
    ...
    for block end

next code...

2) 순회 가능한 객체에서 하나씩 변수에 담은 다음 for 코드 블록을 수행한다. 모든 아이템이 순회되면 for 코드 블록이 종료된다.

a = [1, 2, 3]

for n in a:
    print('{}의 제곱은 {}'.format(n, n**2))
    
>> 1의 제곱은 1
>> 2의 제곱은 4
>> 3의 제곱은 9

여기서 순회 가능하지 않은 숫자형 같은 객체를 a 자리에 두면 에러가 발생한다.

a = 100

for n in a:
    print('{}의 제곱은 {}'.format(n, n**2))
    
>> for n in a:
            ^
>> TypeError: 'int' object is not iterable

dict의 경우 기본적으로 순회를 하게 되면 key를 참조한다. 앞서 데이터 타입, 연산자 (4) 딕셔너리, 셋에서 봤던 keys, values, items도 순회 객체로 사용 가능하다.

a = {'대한민국':'서울', '일본':'도쿄', '중국':'베이징'}
                         # what에 들어가는 것
for what in a:           # key
    print(what, end=' ')
>> 대한민국 일본 중국   
    
for what in a.keys():    # key
    print(what, end=' ')
>> 대한민국 일본 중국 

for what in a.values():  # value
    print(what, end=' ')
>> 서울 도쿄 베이징

for what in a.items():   # (key, value) tuple
    print(what, end=' ')
>> ('대한민국', '서울') ('일본', '도쿄') ('중국', '베이징')
 
for what1, what2 in a.items(): # key, value가 각각 들어감
    print(what1, what2)
>> 대한민국 서울
>> 일본 도쿄
>> 중국 베이징

3) 만약 값과 함께 인덱스도 필요하다면, enumerate함수를 객체로 이용하면 인덱스도 함께 이용 가능하다.

a = ['ㄱ','ㄴ','ㄷ']

for i, c in enumerate(a): # 인덱스, 값 순서
    print(i, c)
    
>> 0 ㄱ
>> 1 ㄴ
>> 2 ㄷ

4) while과 마찬가지로 break(특정 조건에서 종료), continue(특정 조건에서 스킵)를 쓸 수 있다.

a = [1,2,3,4,5]

for n in a:
    if n > 3:
        break         # 3보다 크면 for문 종료
    print(n, end=' ')

>> 1 2 3

for n in a:
    if n > 3 and n < 5: # 4는 출력 스킵
        continue
    print(n, end=' ')
    
>> 1 2 3 5

for문을 쓰다 보면 어떤 문장을 100번 출력하는 코드처럼 굳이 순회 객체의 값이 필요치 않을 때가 생길 수도 있다. 그럼 while문을 쓰면 되지만, for문을 쓰고 싶을 때는 range함수를 이용하면 편하다. range함수는 숫자 리스트를 쉽게 만들 수 있는 내장함수이다.

range(10)             # 0 이상 10 미만
>> range(0, 10)

type(range(10))       # 타입 확인
>> range

list(range(10))       # 리스트로 변환
>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list(range(2, 10))    # 2 이상 10 미만 리스트
>> [2, 3, 4, 5, 6, 7, 8, 9]

list(range(2, 10, 3)) # 2 이상 10 미만 3씩 건너뛴 리스트
>> [2, 5, 8]

list(range(5,51,5))   # 1부터 50까지 5의 배수 리스트
>> [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]

4. 같은 문제를 while과 for로 풀어보기 - 결과는 생략


1) 야호 3번 외치기

for i in range(3):
    print('야호')
##################
n = 1
while n < 4:
    print('야호')
    n += 1

2) 1부터 100까지 더하기

result = 0 # 합이 담길 변수
for n in range(1,101):
    result += n
#############################
result = 0 # 합이 담길 변수
n = 1      # 더해질 수
while n < 101:
    result += n
    n += 1
#############################    
result = 0 # 합이 담길 변수
n = 0      # 더해질 수
while n < 100:
    n += 1
    result += n

3) 구구단 출력하기

a = list(range(2,10)) # 2 ~ 9 숫자 리스트
b = list(range(1,10)) # 1 ~ 9 리스트

for i in a:      # i단
    for j in b:  # 뒤에 곱해지는 수
        print('{} X {} = {}'.format(i, j, i*j))
#################################################
i = 2
j = 1
while i < 10:
    while j < 10:
        print('{} X {} = {}'.format(i, j, i*j))
        j += 1
    i += 1 # 단 바꾸기
    j = 1  # 뒤에 곱해지는 수 1로 초기화
#################################################
while과 for 섞어서 사용도 가능!

4) 이 글 맨 처음에 있던 노란색 펜 찾기

# 노란색 펜이 어디있더라..?
pencil_case = ['파란색 펜', '까만색 펜', '지우개', '자', '노란색 펜', '빨간색 펜', '샤프']
i_need = '노란색 펜'

for what in pencil_case:
    if what == i_need:
        print('찾았어!')
        break
    print('흠..')
##########################
i = 0
while i < len(pencil_case):
    if pencil_case[i] == i_need:
        print('찾았어!')
        break
    print('흠..')
    i += 1

<요약>

 

1. while: 조건이 참일 때 반복수행

 - while 코드 블록 내에 조건이 False가 될 장치 X >> 무한루프

2. for: 순회 객체 아이템을 하나씩 빼내서 반복수행

 - 객체의 끝까지 가게 되면 for문 종료

3. while과 for 모두 break, continue 사용 가능

4. range: 숫자 리스트를 간편하게 만들 수 있는 내장함수