[Python-basic] while, for 반복문
while, for
while 반복문
if문을 비롯한 대부분의 코드들은 위에서 아래로 순차적으로 실행된다. 그러나 때로는 다시 위로 돌아와서 반복하여 실행해야 할 때도 있다. 즉 루프(loop)가 필요하다. 그 중 하나로 while이 있다.
구조)
while 조건문:
실행할 코드 # 조건문이 True일 경우에만 실행
count = 1
while count <= 5:
print(count)
count += 1
1
2
3
4
5
예제1을 보면, count 변수에 1이 대입되어 있다. while문으로 갈 때 조건 count <= 5를 먼저 만난다. 여기서 count = 1이므로 해당 조건을 만족하여 True가 반환된다. 조건이 True이므로 while 문 안의 코드가 실행된다. 위 예제에선 count가 출력되고, 그 후에 count += 1 코드를 통해 count = 2가 된다. 이렇게 while문 안의 코드가 끝까지 실행되었다면 다시 조건으로 돌아가 조건이 맞는지 확인한다. count = 2이므로 count <= 5를 만족하여 또 while 안의 코드를 실행하게 된다. 이러한 과정은 조건문이 False를 반환하게 되면 멈추고 while구문을 빠져나간다. 위 예제에서는 count가 5에서 6이 될 때 조건에 맞지 않게 되어 while을 빠져나가게 된다.
예제1에서 4번째 코드를 통해 코드가 무한 반복되는 것을 막아준다. 만일 이 코드가 없었다면 조건문을 False로 만들어줄 코드가 없게 되는 셈이기에 while 내 코드가 무한 실행된다. 따라서 while문을 쓸 때는 위 예제1의 4번째 코드처럼 while문을 빠져나갈 코드를 반드시 적어야 한다. 아니면 break 구문을 이용하는 방법도 있다.
break 문으로 반복문 빠져나가기
무한 반복문에 break문을 사용하여 while문 안의 코드가 무한 실행되지 않고 적절한 때에 빠져나올 수 있다.
예제2에서는 input() 내장 함수를 이용하여 사용자로부터 문자열을 입력받아 그 문자열을 출력시켜준다. 이 때 q를 입력하면 while문을 빠져나가게끔 break 구문을 쓴다.
while True:
input_string = input("출력할 문자열 입력하세요 (그만두려면 q 입력): ")
if input_string == 'q':
print("여기까지 while, 안녕히 가세요")
break
print(input_string)
출력할 문자열 입력하세요 (그만두려면 q 입력): 안녕
안녕
출력할 문자열 입력하세요 (그만두려면 q 입력): 대충 아무 글
대충 아무 글
출력할 문자열 입력하세요 (그만두려면 q 입력): hello
hello
출력할 문자열 입력하세요 (그만두려면 q 입력): quiz
quiz
출력할 문자열 입력하세요 (그만두려면 q 입력): q
여기까지 while, 안녕히 가세요
참고로 while True로 하면 조건이 항상 True가 되기에 무한루프가 되어 while 아래 들여쓰기된 코드가 무한정 실행된다. 이럴 때 무한 루프를 막기 위해 break가 쓰일 수 있다.
continue로 스킵하기
반복문 실행 시 가끔은 반복문을 빠져나가지 않은 상태에서 어떤 부분은 스킵하여 실행시키지 않고 그냥 지나가길 원할 때도 있다. 이럴 때 continue 키워드를 쓴다.
import random
content = ['게임', '소통', '광고', '먹방', '광고', '야외방송', '음악', '광고']
while True:
input_string = input("무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)")
if input_string == 'q':
break
video = random.choice(content) # content 내 요소 중 무작위로 하나를 추출하여 반환
if video == '광고':
continue # 광고 시러
print("{} 영상을 시청하셨습니다. 다른 영상도 봐보세요!".format(video))
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
소통 영상을 시청하셨습니다. 다른 영상도 봐보세요!
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
음악 영상을 시청하셨습니다. 다른 영상도 봐보세요!
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
음악 영상을 시청하셨습니다. 다른 영상도 봐보세요!
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)
음악 영상을 시청하셨습니다. 다른 영상도 봐보세요!
무작위의 너튜브 영상을 보고 싶다면 엔터키를 눌러주세요. (그만 두려면 q)q
위 예제에서 continue는 if 키워드와 함께 쓰였다. 이 if문을 통해 continue 키워드를 만나면 그 뒤의 코드 (위 예제에서 마지막 줄)들은 실행되지 않고 다시 반복문의 조건문으로 돌아간다.
else문으로 break 여부 확인
while 반복문이 break없이 정상적으로 끝났다면 else 코드로 넘어갈 수 있다. 반대로 말하면, break문으로 while 반복문을 빠져나갔다면 else문은 실행되지 않는다. 이 때 else는 필수로 써야하는 키워드는 아니다.
line1 = ['정상제품', '정상제품', '정상제품']
line2 = ['정상제품', '정상제품', '불량품']
position = 0
print('1번 생산 라인 가동')
while position < len(line1):
inspection = line1[position]
if inspection == '불량품':
print("불량품이 발견되었습니다. 생산 라인 가동 일시 중지")
break
position += 1
else:
print("불량품이 발견되지 않았습니다.")
position = 0
print('2번 생산 라인 가동')
while position < len(line2):
inspection = line2[position]
if inspection == '불량품':
print("불량품이 발견되었습니다. 생산 라인 가동 일시 중지")
break
position += 1
else:
print("불량품이 발견되지 않았습니다.")
1번 생산 라인 가동
불량품이 발견되지 않았습니다.
2번 생산 라인 가동
불량품이 발견되었습니다. 생산 라인 가동 일시 중지
이러한 원리로 while 반복문 실행 시 break가 실행되었는지 여부를 확인할 수 있다.
for 반복문
while 반복문 외에도 for 반복문이 있다. 다음의 예제5에는 while 반복문과 for 반복문이 쓰였는데 둘 모두 같은 기능을 수행한다.
today = ['밥먹기', '씻기', '공부하기', '쉬기', '잠자기']
current = 0
while current < len(today):
print(today[current])
current += 1
print()
for thing in today:
print(thing)
밥먹기
씻기
공부하기
쉬기
잠자기
밥먹기
씻기
공부하기
쉬기
잠자기
다음은 for문의 사용법이다.
for 변수 in 반복자:
실행할 코드
여기서 반복자(iterator)는 string, tuple, list, set, dictionary와 같이 여러 요소들을 (배열처럼) 가질 수 있는 객체들을 말한다. 예제5의 for문에서 today라는 list의 첫 번째 요소 (’밥먹기’)가 변수 thing에 저장되어 print함수를 통해 출력된다. 그 후 today의 다음 요소 ‘씻기’가 thing에 대입되어 for문이 실행된다. 이는 today라는 list 내 마지막 요소까지 진행되고 그 후엔 for문을 빠져나온다.
for문에 반복자로 dictionary가 들어오면 key가 반환된다. 또는 dictionary 함수인 keys()를 써도 key가 반환된다. dictionary의 value가 반환되길 원한다면 values() 함수를 사용하면 된다. key-value 모두 반환되길 원한다면 items()함수를 쓰면 된다. 이 때, for문에 두 개의 변수를 동시에 사용하여 반복자의 값을 받을 수 있다.
some_dict = {
'1': 'a',
'2': 'b',
'3': 'c'
}
for key, value in some_dict.items():
print(key, value)
1 a
2 b
3 c
참고로 for문에도 break, continue, else 키워드를 사용할 수 있다.
for문의 반복자에 빈 객체가 오면 그 for문은 실행되지 않는다.
some_list = []
for data in some_list:
print("print something: ", data)
zip()
list1 = ['1', '2', '3']
list2 = [1, 2, 3]
list3 = ['a', 'b', 'c']
list4 = ['가', '나', '다']
for data in zip(list1, list2, list3, list4):
print(data)
('1', 1, 'a', '가')
('2', 2, 'b', '나')
('3', 3, 'c', '다')
zip() 함수는 여러 반복자들의 요소를 묶어 tuple 형태로 반환하는 함수이다. 위 예제에서, 각 list들의 첫 번째 요소들을 튜플로 묶어 반환하여 실행결과 첫 번째 줄의 결과로 이어졌다. 위 예제에서의 list들의 요소를 세로로 각각 묶었다고 생각하면 된다.
여러 반복자 중 가장 길이가 짧은 반복자의 마지막 요소까지만 요소들을 묶어주고, 그 이후의 요소들에 대해선 아무런 일을 실행하지 않는다.
list1 = ['1', '2', '3', '4']
list2 = [1, 2]
list3 = ['a', 'b', 'c', 'd', 'e']
list4 = ['가', '나', '다', '라']
for data in zip(list1, list2, list3, list4):
print(data)
('1', 1, 'a', '가')
('2', 2, 'b', '나')
예제 8-2에서, list2가 길이가 2로 가장 짧으므로 이 list를 기준으로 zip이 실행되어 총 2개의 zip() 함수의 요소가 반환됨을 알 수 있다.
한 편, for문 외에 일반적으로 zip() 함수를 사용하여 그 반환값을 얻고자 한다면 list(), dict()와 같이 자료형을 변환해주는 함수를 사용해야 한다.
list1 = ['1', '2', '3']
list2 = [1, 2, 3]
some_zip = zip(list1, list2)
print(some_zip)
print(list(some_zip))
<zip object at 0x000002A9195575C0>
[('1', 1), ('2', 2), ('3', 3)]
zip() 함수는 for문 뿐만 아니라 dictionary에도 활용할 수 있다.
korean = ['~에 지원하다', '빌려주다', '연기하다', '통지하다']
english = ['apply for', 'lend', 'postpone', 'notify']
real_dict = dict(zip(korean, english))
print(real_dict)
{'~에 지원하다': 'apply for', '빌려주다': 'lend', '연기하다': 'postpone', '통지하다': 'notify'}
range() 함수로 숫자 배열 생성
range() 함수는 특정 구간의 숫자들을 반복자형으로 반환한다. 사용법은 다음과 같다.
range(시작, 끝, 건너뛰기)
위 인수들은 모두 숫자가 들어간다. ‘시작’을 생략한다면 0부터 시작한다. 그리고 ‘끝’ - 1 까지를 반환한다. ‘건너뛰기’ 인수는 생략해도 된다. 생략하면 1이 기본값으로 설정된다. 예를 들어 ‘건너뛰기’ 인수에 2를 대입하고 ‘시작’, ‘끝’에 각각 1, 10을 대입했다면 반환값은 1, 3, 5, 7, 9가 된다. ‘건너뛰기’ 인수에 -1을 대입하면 숫자들의 순서가 거꾸로 바뀐다.
for x in range(1, 10):
print(x)
1
2
3
4
5
6
7
8
9
for x in range(1, 10, 2):
print(x)
1
3
5
7
9
for x in range(10, 0, -1):
print(x)
10
9
8
7
6
5
4
3
2
1
for문에 대한 예제6부터 쭉 보면, for문에 들어갈 반복자를 위해 for문 앞에 미리 반복자를 변수를 따로 정의하고 대입하여 사용했다. 변수를 정의하고 그 변수에 값을 대입하는 것 자체가 컴퓨터의 메모리를 차지한다. 그런데 for문에 range() 함수를 쓰면 range()는 for문이 실행될 때만 존재하고 for문이 끝나면 사라지기에 메모리를 차지하지 않는다는 장점이 있다.
zip()함수와 마찬가지로 range() 자체는 출력 시 값이 아닌 엉뚱한 것이 출력되므로 for문 안에 쓰거나 아니면 list(), dict()와 같은 함수들을 적절히 활용해야 한다.
Reference
[1] Bill Lubannovic, “Introducing Python” (O’REILLY, 2015)
This content is licensed under
CC BY-NC 4.0
댓글남기기