점프 투 파이썬 : https://wikidocs.net/book/1
파이썬 기본을 갈고 닦자 : https://wikidocs.net/16031
보통 대부분의 언어가 반복문으로 for, while
이 있다. (go는 for문만 있다) 파이썬 역시도 for, while
로 구성되어있으므로 하나씩 알아보자.
반복해서 문장을 수행할 때, 반복문을 사용한다. 이 while
문은 다음과 같은 구조를 갖는다.
while 조건:
본문
본문
while
은 조건이 참인 경우에만 반복문을 수행한다. 즉, 조건이 거짓이 되면 반복문 수행을 종료한다. 그렇다고 반복되는 와중에 갑자기 종료된다는 것이 아니라, 조건을 검사했을 때 False
이면 종료한다는 것이다.
count = 0
while count < 10:
count += 1
if count == 5:
count = 10
print(count) # 1 2 3 4 10
print(count) # 10
다음의 반복문을 보면 count
가 10이하이면 반복해서 count을 하나씩 더하고 while
문을 반복한다. 즉 다음의 순서로 반복한다는 것이다.
while문
조건인 count가
10보다 작은가??while의
본문으로 들어간다.count
가 하나 더해진다.count
가 5와 같은 지 확인을 한다.count
가 5와 같으면 count
는 10이 된다.print
이 실행되어 count
값이 찍힌다.count
가 10보다 작지 않다면 while문
을 종료한다.이 때 if
문에 의해서 count
가 5가 되면 count
를 10으로 채운다.
여기서, count가 10보다 작지 않고, 같으므로 while문
이 뙇 종료되는 것이 아니다. 이 증거로 print
문이 if문
다음인데 10
을 프린트한 것을 보면 알 수 있다.
즉, 반복문이 종료되는 것은 본문에서 조건문의 변수를 아무리 바꾸어 종료조건이 성립되도 반복문이 자신의 조건을 검사할 차례 때까지 본문을 실행한다.
물론 break
를 사용하면 원하는 위치에서 while
문을 종료시킬 수 있는데 이는 뒤에 배운다.
break
문은 while
문 뿐만 아니라, for
문과 같은 반복문에도 쓰일 수 있다. 이를 이용하면 본문이 구동될 때 특정한 조건이 성립하는 경우 반복문을 종료할 수 있다.
count = 0
while count < 10:
count += 1
if count == 5:
count = 10
break
print(count) # 1 2 3 4
print(count) # 10
다음의 코드는 위의 코드에서 if count == 5
이면 count = 10
을 하고 break
시키는 코드이다. 이전에는 while
문의 조건문까지 돌아야 count
의 값이 10임으로 알고 종료되었는데, break
를 사용하면 즉시 반복문이 종료된다.
이에 따라, count = 10
일 때 본문의 print
문이 실행되지 않고, 반복문을 종료하기 때문에 결과로 1 2 3 4
만 나오고, 반복문을 종료한 print
에서 10
이 나온다.
그러나 만약, 반복은 하되 특정 부분은 처리하고 싶지 않을 때는 어떻게 해야할까? 종료시키고 또 반복문을 돌게하면 너무 비효율적이다. 그래서 continue
를 사용한다.
continue
가 작동하면, 반복문의 본문 구동을 중단하고 다음 라운드로 넘어간다. 여기서 다음 라운드라는 것은 반복문의 조건
을 말한다. 즉, 남은 본문 부분은 실행하지않고 조건부분으로 간다는 것이다.
count = 0
while count < 10:
count += 1
if count % 2 == 0: continue
print(count) # 1 3 5 7 9
print(count) # 10
다음과 같이 count
는 반복문을 순회할 때 하나씩 더해진다. 이 때 if
문에서 count % 2 == 0
을 만나면 count
가 짝수인 경우는 다음 반복문으로 넘어가게 된다.
그렇게 되면 다시 반복문의 나머지 본문인 print
를 넘기게 되고, while
의 조건쪽으로 넘어가게 된다.
이에 따라, count
는 짝수인 경우를 print
하지않고 넘어가며 count
를 하나씩 추가한다. 그리고 while
문의 조건부를 계속검사하며 마침내 count
가 10
이 되는 순간 종료한다.
사실 while
문 보다 많이 사용되는 반복문이 바로 for
문이다.
for
문은 while
문보다 사용하기 쉽고, 여러기능을 제공한다.
기본구조는 다음과 같다.
for 변수 in iterable:
본문1
본문2
...
여기서 iterable
은 리스트, 튜플, 문자열
을 말하며 첫번째 요소부터 마지막 요소까지 가져온다. 그리고 이 요소들은 매 라운드마다 변수에 할당되는 것이다.
values = [123, 124, 643, 0]
for value in values:
print(value) # 123 124 643 0
이 처럼, 리스트안에 있는 요소들이 value
에 매 라운드마다 들어가는 것이다. 리스트의 마지막 요소까지 반복하고 종료한다.
리스트안에 튜플이 있는 경우, 다음과 같이 요소들을 가져올 수도 있다.
a = [(1,2), (3,4) , (5, 6)]
for first, second in a:
print(first, second) # 1 2 , 3 4 , 5 6
리스트 안에 있는 요소가 튜플인 경우, 튜플안의 값들을 변수에 각각 할당할 수 있다. 마치 자바스크립트의 비구조화 할당과 같은 개념으로 튜플이 이런게 가능했다는 것은 이전에도 확인했다.
그럼 매번 반복할 때마다, 원하느 값들을 리스트로 만들어서 주어야 할까?? 이건 사실 조금 불편하다. 그래서 range
라는 것이있다.
정수 0에서부터 10까지의 수를 만든다고하자, 다음처럼 일일히 만들어주는 것은 매우불편한 일이다.
count = 0
values = []
while count < 10:
values.append(count)
count += 1
print(values) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
다음의 코드는 너무 복잡하고, 귀찮다. 그래서 우리는 range()
를 사용하도록 하자, range
를 사용하면 특정 범위의 정수값을 생성하여 iterable한 range
객체로 돌려준다.
사용방법은 다음과 같다.
range(end) # 0~end-1까지 정수생성
range(start, end) # start부터 end-1까지 정수생성
range(start, end, step) # start부터 end-1까지 정수를 생성하되 step만큼 증가
range
객체를 in
과 함께쓰면 range
객체가 iterable
하므로 for
문을 통해 element
를 하나씩 가져올 수 있다.
for elem in range(10):
print(elem, end=" ") # 0 1 2 3 4 5 6 7 8 9
바로 이렇게 말이다. 참고로 print(elem, end=" ")
라고 쓰면 출력하는 마지막에 공백을 추가한다. 기본적으로 개행문자인 \n
으로 되어있어 한줄을 띄게되는 것이다.
다음과 같이 다양하게 사용할 수 있다.
for elem in range(10):
print(elem, end=" ") # 0 1 2 3 4 5 6 7 8 9
for elem in range(5,10):
print(elem, end=" ") # 5 6 7 8 9
for elem in range(5,10, 2):
print(elem, end=" ") # 5 7 9
조심할 것은 range
의 경우 end값
은 포함하지 않는다는 것이다. 즉, 마지막 값은 포함하지 않으므로 end-1
까지라고 쓴 것이다.
for문 역시도 break
와 continue
를 사용할 수 있다.
for elem in range(10):
if elem == 5:
break
print(elem) # 0 1 2 3 4
print(elem) # 5
for
문이 계속 순회하여 print
를 만나 0 1 2 3 4
를 출력하게 된다. 여기서 elem == 5
를 만나면 break
되어 순회를 종료하게 된다.
마찬가지로 continue를 쓰면 해당 라운드만 넘기고 다음 라운드로 간다.
for elem in range(10):
if elem == 5:
continue
print(elem) # 0 1 2 3 4 6 7 8 9
print(elem) # 9
다음의 결과를 보면 elem
가 5
일 때만 쏙 빠진 것을 확인할 수 있다. 이를 통해 for
문에서 continue
가 잘 작동하는 것을 확인할 수 있다.
리스트 안에 for문을 포함하는 리스트 내포(list comprehension)을 사용하면 좀 더 편리하고 직관적인 프로그램을 만들 수 있다.
사용 방법은 다음과 같다.
result = [본문 for elem in iterable]
위에서 range
를 사용하여 0~9까지의 값을 만들었다면, 이를 이용하여 list에 값을 넣어보도록 하자
result = []
for elem in range(10):
result.append(elem)
print(result) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
이를 리스트 내포(list comprehension)을 사용하여 표현해보자
result = [elem for elem in range(10)]
print(result) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
훨씬 코드가 단순해졌다. 솔직히 쉬운지는 잘 모르겠으나 일단 간단해보이긴한다.
그러나, 만약 짝수를 거르고 홀수만 담고 싶다면 어떻게해야할까?? 재밌게도 리스트 내포에서도 if
문을 담을 수 있다.
result = [elem for elem in a if 조건]
이런 식이다. 즉, if조건이 맨 뒤로간다. 조심해야할 것은 if문
을 통과한 elem
만 리스트로 담겨진다는 것이다.
이를 이용하여 홀수만 있는 리스트를 만들어보자
result = [elem for elem in range(10) if elem % 2 == 1]
print(result) # [1, 3, 5, 7, 9]
조금 복잡하지만 for문을 2개 이상 사용하는 것도 가능하다. 물론 이 경우는 그냥 풀어쓰는게 가독성에 좋다.
result = [x*y for x in range(2, 10)
for y in range(1,10)]
print(result)
# [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]
enumerate()
는 인자로 리스트나 문자열, 튜플과 같은 iterable
을 받으면 해당 element
가 반복 몇 번째에 해당하는 지 나타낸다.
t = [1, 5, 32, 14, -1, 23]
for value in enumerate(t):
print(value)
#(0, 1)
#(1, 5)
#(2, 32)
#(3, 14)
#(4, -1)
#(5, 23)
다음과 같이 enumerate
에 iterable
이 오면 튜플을 만들고 튜플안에 몇 번째 반복에 해당하는 값인지 나타낸다.
튜플이기 때문에 다음과 같이 받을 수 있다.
t = [1, 5, 32, 14, -1, 23]
for i, v in enumerate(t):
print(i , v)
#0 1
#1 5
#2 32
#3 14
#4 -1
#5 23
즉, 튜플 할당이 가능하다.