반복문 (for / while) - else 문 개념
파이썬에서는 다른 프로그래밍 언어와 다르게 반복문 for과 while문에 else를 같은 indentation에 놓을 수 있다. 그 else의 기능은 무엇일까? 반복문 도중 break가 되지 않고 끝까지 반복을 실행했을 경우 else에 있는 코드를 실행하게끔 하는 것이다. 코드를 통해 바로 알아보자.
코드 예시
(1) 간단한 예시
특정 요소가 리스트 안에 있는지 없는지 확인하고 싶다고 해보자. for-else 문을 이용하면 다음과 같이 깔끔하게 코드를 짤 수 있다.
bucket = ['딸기', '당근', '수박', '참외', '메론']
for fruit in bucket:
if fruit == '딸기':
print('딸기가 바구니에 있습니다!')
break
else:
print('바구니엔 딸기가 없군요.')
# 결과 :
# '딸기가 바구니에 있습니다!'
이 반복문과 else의 조합은 어떠한 효용을 가질까? 보통 반복문을 돌릴 때 반복문 내에 break를 두는 경우가 많은데, break로 인해 반복문을 빠져나왔는지, 반복문이 멈추는 조건이 될 때까지 반복한 후 정상적으로 빠져나왔는지 알 수 없기 때문에 확인을 하기 위해 임시 변수를 두는 경우가 많다. 굳이 임시 변수를 두지 않더라도 어떠한 방식으로 반복문을 빠져나오게 되었는지는 꼭 확인을 해봐야 한다. 하지만 반복문과 else의 조합을 이용하면 그러한 확인 과정을 거치지 않아도 된다는 장점이 있다.
(2) 이진 탐색 알고리즘 (Binary Search Algorithm)
이진 탐색 알고리즘을 통해 조금 더 자세히 알아보자. 아래 코드는 이진 탐색 알고리즘으로, 인자로 주어진 리스트 'lst' 안에 찾고자 하는 값 'target'이 존재한다면 해당 target의 index를 반환하고, 존재하지 않다면 -1을 반환하는 코드이다.
def BinarySearch(lst, target):
answer = 0
start = 0
end = len(lst) - 1
mid = (start + end) // 2
while start <= end:
if target == lst[mid]:
answer = mid
break
elif target > lst[mid]:
start = mid + 1
mid = (start + end) // 2
elif target < lst[mid]:
end = mid - 1
mid = (start + end) // 2
if start > end: # 여기에 "else:" 만 딱 들어가면 손쉽게 해결.
answer = -1
return answer
else를 쓰지 않는다면 18번 줄에 있는 조건문처럼 while문을 정상적으로 빠져나오게 된 것인지, break를 통해 빠져나오게 된 것인지 확인을 해 주어야 한다. 하지만 해당 조건문 대신 "else:"만 넣어주면 같은 기능을 하는 코드가 손쉽게 완성된다. 해당 예시에서는 확인해내는 조건문이 간단했지만, 보통은 임시로 Bool형 변수나 int형 변수를 이용하여 확인하는 경우가 많다. 아래의 또 다른 예시를 살펴보자.
(3) 프로그래머스 코딩테스트 문제 - 스킬 트리
아래 코드는 며칠 전 포스팅했던 코딩테스트 문제 '스킬 트리'의 제출 코드다. 해당 문제에 대한 설명과 코드에 대한 자세한 설명이 궁금하다면 여기서 확인하자.
해당 코드에 있는 첫 번째 함수에서는 check라는 Bool형 변수를 하나 만들어주어 7번~13번 라인에 해당하는 for문이 정상적으로 종료된 것인지 break되어 종료된 것인지 확인하고 있다. 하지만 두 번째 함수에서는 check라는 변수를 사용하지 않고 for-else 구문으로 깔끔하게 코드를 구성했다. 굳이 사용하지 않아도 되는 변수라면 없애버리고 2줄이나 줄일 수 있는데 한 줄이라도 더 짧게 짜고 싶은 나로서는 꽤 괜찮은 기능이라고 생각된다.
# 확인용 변수 check를 사용한 코드
def solution1(skill, skill_trees):
count = 0
for i in range(len(skill_trees)):
status = 0
check = True
for j in range(len(skill_trees[i])):
if skill_trees[i][j] in skill:
if skill.index(skill_trees[i][j]) != status:
check = False
break
else:
status += 1
if check == True:
count += 1
return count
# for-else를 사용한 코드
def solution2(skill, skill_trees):
count = 0
for i in range(len(skill_trees)):
status = 0
for j in range(len(skill_trees[i])):
if skill_trees[i][j] in skill:
if skill.index(skill_trees[i][j]) != status:
break
else:
status += 1
else:
count += 1
return count
'Dev > Python' 카테고리의 다른 글
[파이썬/Python] Collections - Deque (0) | 2020.10.09 |
---|---|
[파이썬/Python] 리스트(list)의 메소드 시간 복잡도(Big-O) 정리 (0) | 2020.04.20 |
[파이썬/Python] 리스트의 정렬 방법 - sort함수와 sorted함수 (0) | 2020.03.11 |
[파이썬/Python] 순열과 조합 (Permutation and Combination) (0) | 2020.03.10 |
[파이썬/Python] 재귀함수(Recursive function)와 메모이제이션(Memoization) (2) | 2020.03.02 |