목차
1. while 문
2. 제어문 심화
시간이 모자랐던 어제, 밀린 TIL을 마무리해본다. 이미 TIL에서 Today는 물건너갔다.
while 문
정해진 조건에 해당하지 않게 될 때까지 반복적으로 수행한다.
반복시킨다는 점에서는 for문과 비슷하지만 일반적으로 사용법이 다르다고 한다.
각자가 동작하는 원리를 보면
- for 문 : iterabel한 자료형의 요소들을 하나씩 훑으며 시행한다.
- while 문 : 특정 조건을 충족하는 한 무한히 수행한다.
이런 차이가 있는데, 따라서 for문은 list, dict등을 채우거나,
해당 자료의 요소마다 연산을 시행할 때 쓴다.
하지만 while문은 심플하게 동작을 반복한다.
강사님 설명으로는 while문이 잘 안 쓰인다던데,
for문으로 대체가능해서 그런 걸까...?
여튼 while문은 일반적으로 두 방법으로 쓴다.
- 조건 변수가 변할 때, while 문의 조건을 변수 범위처럼 사용
# 리스트 만들기
fruits = ['apple', 'banana', 'cherry']
# 요소 출력
i = 0 # i를 0으로 초기화함
while i < len(fruits) :
print(fruits[i])
i += 1
apple
banana
cherry
0으로 초기화한 반복자 i를 매 iteration마다 1씩 증가시켜
리스트 fruits의 각 인덱스를 돌게 만든다.
확실히 for문으로 대체 가능해 보인다.
# 리스트 만들기
fruits = ['apple', 'banana', 'cherry']
# 요소 출력
for i in fruits:
print(i)
apple
banana
cherry
이게 더 간단한 것 같기도 하고.
1부터 100까지 3의 배수를 더한다 치면
# while을 사용한 방법
tot = 0
n = 0
while n < 101:
if n % 3 == 0:
tot += n
n = n + 1
else :
n = n + 1
print(tot)
#for을 사용한 방법
tot = 0
n = 0
for i in range(101):
if n % 3 == 0:
tot += n
n = n + 1
else :
n = n + 1
print(tot)
이것도 큰 차이는 없는 것 같다.
생각해보면 어차피 지정된 범위 안에서 돌리는 거나 마찬가지라서, 별로 유용하지는 않아 보인다.
- 무한루프에 빠뜨리고 break 조건 달기
그래서일까, 지금은 while문을 쓰는게 더 좋은 상황을 이것밖에 모르겠다.
# 변수 선언
tot, i = 0, 0
# 100까지 짝수 합 구하기
while True: ## 무한루프 설정
i = i + 1 ## i를 1식 누적시키며 진행
if i > 100: ## 100부터 종료
break
if i % 2 == 0: ## 짝수합 구하기
tot = tot + i
# 확인
print(tot)
2550
뭐... 이것도 for문으로 범위 지정하면 되는 문제지만, 범위에 대한 정보가 없거나 할 때 유용하지 않을까?
무엇보다 문돌이 눈에는 직관적이어서 마음에 든다(...)
마지막으로 while문 심화 문제로 배운 건데,
- 5,000원의 돈을 갖고 있습니다. 동료들과 AIVLE 로봇카페에서 아메리카노를 구매하려고 합니다. (아메리카노는 한잔에 1,300원)
- 갖고 있는 돈을 변수 money, 커피 한 잔의 가격을 변수 coffee에 저장합니다.
- '아메리카노를 구입하시겠습니까?'에 대한 대답을 입력받아, 대답이 '네'일 경우 커피가 판매됩니다.
- 다른 대답을 할 경우 '다시 입력해 주세요.'라고 출력합니다.
- 한 잔을 구매할 때마다 남은 돈을 변수 money에 저장하여 출력합니다.
- 커피를 살 돈이 모자랄 경우 '돈이 모자랍니다. 커피를 구입할 수 없습니다.'라고 출력하고 종료합니다.
- 힌트: while 문 내에서 if 조건문을 중첩해서 사용해야 합니다.
# 내 코드
money = 5000
coffee = 1300
while True:
s = input('아메리카노를 구입하시겠습니까?')
if (s == '네') & (money >= coffee):
money -= coffee
print(f'남은 소지금: {money}원')
elif (s == '네') & (money < coffee):
print('돈이 모자랍니다. 커피를 구입할 수 없습니다.')
break
else:
while True:
s1 = input('다시 입력해 주세요.')
if s1 == '네':
break
원래 코드에서 많이 수정했다.
맨 처음에는 '아니오'를 입력했을 때 '다시 입력해 주세요'에서 한번 더 '아니오'를 하면 처음으로 돌아오는 문제를 겪었다.
그래서 시행착오 끝에 '다시 입력해 주세요'를 무한루프에 한번 더 빠뜨렸는데.....
# 정답 코드
money = 5000
coffee = 1300
while True:
print('커피를 구입하시겠습니까?')
a = input()
if a == '네':
if money < coffee:
print('돈이 모자랍니다. 커피를 구입할 수 없습니다.')
break
money -= coffee
print(money)
else:
print('다시 입력해 주세요.')
if문을 중첩하지 않고 조건을 한 줄에 다 달아 버린 것이 문제였던 것 같다.
제어문 심화
크게 두 가지를 배웠다.
- for문으로 반복자를 리스트나 딕셔너리에 태우기
- 확장 문법
전자는 AICE 준비하면서 몇번 본 적 있고,
후자는 난생 처음 본다.
- 리스트나 딕셔너리에 태우기
# 리스트 만들기
member = ['홍길동', '한사랑', '일지매', '박여인', '강우동']
index_num = 0
# 루프 돌면서 이름 출력
for name in member:
index_num += 1
print(f'{index_num}. {name}', sep='')
너무나 많이 쓰이는 방법, 반복자가 리스트의 값들을 하나씩 돈다.
enumerate()라는 함수도 같이 배웠는데, 리스트의 index와 value를 튜플로 반환한다.
리스트를 묶어서 item화 된다는 점에서는 좋은데, 인덱스가 딸려 나오는 건 좀 불편할 것 같다.
한편 이 방법은 너무나 중요하게 쓰이는데, 예를 들어
sample_list = ['1', '2', '3', '4', '5']
new_list = []
for i in sample_list:
i = int(i)
new_list.append(i)
print(type(new_list[0]))
이렇게 리스트의 타입을 바꿀 수 있다.
여기서 중요한 것, 확장 문법이 등장한다.
- 확장 문법
나는 이 방법이 아주 마음에 들었다.
바로 위에 나오는 리스트 타입 바꾸기는 빈 리스트도 선언해야 하고,
또 조건이라도 붙는 순간 몇 줄이 되어 버린다.
하지만 위의 코드를 확장 문법으로 쓰면
sample_list = ['1', '2', '3', '4', '5']
new_list = [int(i) for i in sample_list]
print(type(new_list[0]))
이렇게 줄어든다.
지금 진행중인 코딩마스터스 문제에 적절한 예시가 있는데,
사족이나, 나중에 코딩마스터스 문제도 쭉 풀이하는 카테고리를 팠으면 좋겠다.
문제
등차수열에서 첫 항인 a, 두 항의 차인 b, 몇번째 항인지 나타내는 n이 입력되었을 때 n번째 항을 출력하는 프로그램을 짜라.
입력받아야 하기 때문에 sys.stdin.readline().strip()을 쓰게 되는데,
input()도 그렇지만 사용자에게 입력받는 녀석은 늘 문자열이다.
어떻게든 계산을 위해 저 문자열을 정수인 리스트로 만들어야 하는데,
이때도 코드 한 줄로 가능하다.
input_list = [int(x) for x in input_str.split()]
강사님 스타일로 해석하자면
나 리스튼데([])
정수 x를 쓸거야(int(x))
근데 얘는 input_str.split()에서 하나씩 빼온 거야(for x in input_str.split())
이런 방식이지.
그리하여 완성된 정답
import sys
input_str = sys.stdin.readline() # 문제 조건 : 세 수가 공백으로 구분되어 주어진다.
# 리스트로 변환 후 변수 할당
input_list = [int(x) for x in input_str.split()]
A, B, N = input_list
# 함수 선언
def ap(A, B ,N):
print(A + (B * (N-1)))
# 출력
ap(A, B, N)