[파이썬 기초] 4. 조건문과 반복문
이번엔 조건문과 반복문에 대해 알아보겠습니다.
1. 조건문 (if문)
2. 반복문
2.1. While문
2.2. for문
2.3. 이중 반복문
1. 조건문 (if문)
조건문은 특정 조건을 만족했을 때만 실행되도록 하는 코드입니다.
a = 3
if a < 5:
print("5보다 작습니다.")
위 코드는 변수 a가 5보다 작은 값일 경우 "5보다 작습니다." 를 출력하는 코드입니다.
조건문은 if 옆에 원하는 조건을 작성하고, 해당 조건을 만족할 때 실행될 코드를 들여쓰기를 통해 구현하면 됩니다.
조건은 보통 2개 값의 비교를 통해 결정됩니다. 이 때 비교에 사용되는 기호 몇가지를 먼저 알아 보도록 하겠습니다.
기호 | 의미 | 기호 | 의미 |
A > B, A < B | A가 B보다 크다, B가 A보다 크다 | A >= B, A <= B | A가 B보다 크거나 같다. B가 A보다 더 크거나 같다. |
A == B, A is B | A와 B가 같다. | A != B | A와 B가 같지 않다. |
not A | A가 아니다. | A | A이다. |
a in A | a가 리스트 A에 속한다. |
위와 같은 기호들이 if 옆에 들어갈 수 있으며, 해당 조건을 만족한다면 if문 내의 코드들을 실행하게 됩니다. 위에서 볼 수 있듯이 보통 두 변수를 비교하는 식으로 많이 사용됩니다.
위 기호들의 쉬운 이해를 위해 몇 가지 조건문들을 직접 작성하고 실행해 보겠습니다.
A = 10
B = 20
ListA = [5, 10, 15, 20]
if A <= B:
print("B가 A보다 크거나 같습니다.")
if A != B:
print("A와 B는 같지 않습니다.")
if A + 10 == B:
print("A에 10을 더한 값은 B와 같습니다.")
if True:
print("조건이 항상 참(True)이므로 무조건 실행됩니다.")
if not (A > B):
print("A가 B보다 크다면 실행되지 않습니다.")
if A in ListA:
print("A는 ListA에 속합니다.")
이 외에도 직접 변수값이나 조건들을 바꿔가며 직접 실험해 보시기 바랍니다.
and나 or를 사용해 2개 이상의 조건을 걸 수도 있습니다.
A = 5
B = 10
if A%2 == 0 and B%2 == 0:
print("A와 B가 둘 다 짝수일 때 실행됩니다.")
if A%2 == 0 or B%2 == 0:
print("A와 B 둘 중 하나라도 짝수일 때 실행됩니다.")
위와 같이 'and'를 사용한다면 2개의 조건을 모두 만족할 때 코드가 실행됩니다.
'or'를 사용한다면 2개의 조건 중 하나라도 만족된다면 코드가 실행됩니다.
elif를 이용해 조건을 여러개를 건다면 코드를 분기점처럼 짤 수도 있습니다.
A = 30
if A < 10:
print("A는 10 이하입니다.")
elif A >= 10 and A < 20:
print("A는 10 이상이고 20 미만입니다.")
else:
print("A는 20 이상입니다.")
만약 A가 5라면, 맨 첫번째 조건 (if A < 10)에 걸리므로 "A는 10이하입니다." 가 출력되게 됩니다. 그리고 조건문을 만족했으므로 아래의 elif와 else는 확인하지 않고 코드가 넘어갑니다.
만약 A가 15라면, 첫번째 조건을 만족하지 않습니다. 그러므로 다음 조건인 elif문을 확인합니다. elif의 조건은 (A >= 10 and A < 20) 이므로 이를 만족하기 때문에 "A는 10 이상이고 20 미만입니다."를 출력하게 됩니다. elif의 조건을 만족했으므로 else는 확인하지 않고 코드가 지나갑니다.
만약 A가 25라면, if와 elif의 조건을 모두 만족하지 않습니다. 그렇기 때문에 마지막인 else의 코드를 실행하게 되어 "A는 20 이상입니다."를 출력하게 됩니다.
elif는 여러개 쓸 수 있으며, if와 같이 옆에 조건을 작성해 줘야 합니다.
else는 하나만 쓸 수 있으며, 무조건 가장 마지막에 작성해 줘야 합니다. 위의 조건을 모두 만족하지 않을 경우 실행되는 코드니까요.
그럼 왜 elif, else를 사용할까요? 그냥 if를 여러개 쓰면 안될까요? 둘의 차이점을 한번 코드를 직접 실행해 보면서 확인해 볼까요?
A = 10
print("if문을 3개 썼을 때,")
if A < 100:
print("A는 100보다 작다.")
if A < 50:
print("A는 50보다 작다.")
if A < 20:
print("A는 20보다 작다.")
print("elif와 else를 썼을 때,")
if A < 100:
print("A는 100보다 작다.")
elif A < 50:
print("A는 50보다 작다.")
elif A < 20:
print("A는 20보다 작다.")
if문을 3개 쓴 경우엔 변수 A(=10)는 3개의 if문을 모두 만족하므로 3개의 문장이 모두 출력됩니다.
반대로 elif를 쓴 코드의 경우, 변수 A가 3개의 조건을 모두 만족함에도 맨 위의 "A는 100보다 작다."만 출력하게 되죠. 이제 차이를 알겠나요?
elif, else를 사용한다는 것은 상위의 조건을 만족하지 못했을 때 확인하는 꼬리조건 같은 겁니다.
반대로 if 문을 여러개 쓰는 것은 조건끼리 서로 관계 없이 그냥 각 조건들을 따로 확인하게 됩니다.
2. 반복문
반복문은 코드가 연속으로 여러번 반복해서 실행해야 할 때 쓰는 코드입니다.
반복문은 while문과 for문 2가지가 있습니다. 지금부터 반복문에 대해 알아 보겠습니다.
2.1. While문
while문은 '~하는 동안' 이라는 의미와 같이 특정 조건을 만족하는 동안 코드를 반복하는 것을 말합니다.
a = 5
while a < 7:
print(a)
a += 1
while a < 7: 은 변수 a가 7보다 작다면 아래의 코드를 반복한다는 뜻입니다.
처음엔 a의 값이 5이기 때문에 조건을 만족합니다. 그렇기 때문에 while 아래의 print(a)와 a+=1 이 실행됩니다.
그러면 a가 6이 됐겠죠? 여전히 7보다 작기 때문에 while 아래의 코드를 실행합니다.
이제 a는 7입니다. 그러면 a < 7 조건을 만족하지 못합니다. 그러니 아래의 코드가 실행되지 않고 코드가 종료되게 됩니다.
위 반복문을 실행했을 때 일어나는 일을 순서도로 그려 보면 아래와 같습니다.
코드가 실행되면 5, 6까지 출력이 된 뒤에, 마지막으로 변수 a의 값이 7이 됐으므로 조건을 만족하지 않아 while문을 종료하고 코드를 종료하게 됩니다.
while문을 사용할 때 주의할 점은, 반복문이 확실히 종료될 수 있도록 코드를 작성해야 한다는 것입니다.
위에 작성한 코드의 경우 변수 a의 값에 1씩 더해서 언젠가 코드가 종료될 수 있도록 하고 있습니다.
a = 5
while a < 10:
a -= 1
만약 코드가 위와 같이 작성된다면 변수 a는 항상 10보다 작기 때문에 코드가 무한반복 되겠죠. 그러면 무한 반복 에러가 발생하면서 코드가 종료되게 됩니다.
혹은 무한반복 코드를 작성하고 종료 조건을 if문을 사용해 직접 명시하는 식으로 코드를 작성하는 것도 가능합니다.
a = 10
while True:
if a < 20:
a += 1
else:
break
while True를 쓰면 조건이 항상 참이기 때문에 코드가 무한반복되게 됩니다. 그렇기 때문에 if문을 이용해 a가 20보다 작지 않게 된다면 반복문을 종료하도록 break를 써서 반복을 종료하도록 한겁니다.
break는 반복문을 종료하는 기능을 합니다.
while문의 조건도 if와 같이 and, or, not을 사용할 수 있습니다.
a = 50
while a < 100 and not a % 10 == 0:
a -= 5
2.2. for문
while문이 조건에 따른 반복이었다면 for문은 반복 횟수를 지정할 수 있는 반복문입니다. 우선 for문의 생김새를 먼저 보겠습니다.
for i in range(0, 5, 1):
print(i)
# 0
# 1
# 2
# 3
# 4
위 코드를 실행하면 0부터 4까지 출력하고 코드가 종료됩니다.
코드 첫 줄을 보겠습니다. 우선 뒤의 range(0, 5, 1)을 먼저 알려드리겠습니다. range()의 첫번째 인자는 시작 인덱스를 나타냅니다. 그리고 두번째 인자는 끝 인덱스를, 마지막 세번째 인자는 간격을 의미합니다.
위 코드는 range(0, 5, 1)이므로, 0부터 5까지 1의 간격으로 숫자를 증가시킨다는 의미를 가리킵니다. 즉, 'for i in range(0, 5, 1)'은 변수 i를 0~5까지 1 간격으로 숫자를 증가시킨다는 말입니다.
여기서 주의할 점은, 마지막 숫자는 포함되지 않는다는 겁니다. 위 코드의 경우에도 0부터 5까지지만 5는 출력되지 않습니다.
for i in range(2, 10, 3):
print(i)
위 코드를 실행하면 어떤 숫자들이 출력될까요? 숫자를 직접 바꿔가면서 결과를 확인해 보시기 바랍니다.
for i in range(5):
print(i)
for i in range(3, 10):
print(i)
위와 같이 range() 안에 3개의 인자를 모두 넣지 않더라도 코드는 작동합니다. 숫자를 하나만 넣었을 경우, 시작 인덱스는 자동으로 0이 되고, 입력한 숫자가 끝 인덱스가 됩니다. 그리고 간격은 자동으로 1이 됩니다.
즉, for i in range(5): 는 0부터 5까지 숫자가 1씩 증가한다는 의미와 같습니다.
숫자를 2개쓰면 시작 인덱스와 끝 인덱스가 지정되고 증가하는 간격은 자동으로 1이 됩니다.
즉, for i in range(3, 10): 은 3부터 10까지 숫자가 1씩 증가한다는 의미와 같습니다.
또, 대부분 for문에는 변수 i를 사용하지만 꼭 이름을 i로 할 필요는 없습니다. 보통 index의 약자인 i를 많이 사용하긴 하지만 필요에 따라 다른 변수 이름을 넣어도 됩니다.
for문은 횟수 반복뿐만 아니라 리스트의 요소들에 접근하는데도 사용할 수 있습니다. 예를 들면,
listA = ['a', 'b', 'c', 'd', 'e']
for a in listA:
print(a)
# 'a'
# 'b'
# 'c'
# 'd'
# 'e'
위와 같이 코드를 작성하면 리스트의 요소들을 하나씩 출력하게 됩니다. 이처럼 for문은 range()를 통해 직접 범위를 지정하거나, 리스트의 요소들에 접근하는데 사용할 수 있습니다!
리스트 요소에 접근할 때는 zip, enumerate를 추가해 사용할 수도 있습니다.
enumerate는 리스트의 요소와 인덱스에 함께 접근하는 방법입니다.
listA = ['a', 'b', 'c']
for i, a in enumerate(listA):
print(i, a)
# 0, 'a'
# 1, 'b'
# 2, 'c'
보면 enumerate()의 괄호 안에 리스트를 넣을 경우, i와 a 2개의 변수를 사용할 수 있습니다. 그리고 각 변수는 인덱스와 리스트의 요소를 가리킵니다. 이름이 꼭 i, a일 필요는 없으며 앞에 있는 변수가 인덱스를, 뒤에 있는 변수가 요소값을 나타냅니다.
zip()은 2개 이상의 리스트를 함께 보고 싶을 때 사용됩니다.
listA = ['a', 'b', 'c']
listB = [3, 5, 7]
for a, b in zip(listA, listB):
print(a, b)
#'a', 3
#'b', 5
#'c', 7
zip안에 여러 개의 리스트를 넣으면 리스트의 각 요소들을 for문을 통해 볼 수 있습니다. 만약 zip() 안의 리스트들의 길이가 서로 다르다면, 길이가 짧은 리스트에 맞춰서 반복이 진행됩니다.
listA = ['a', 'b', 'c']
listB = [3, 5, 7, 11, 13, 21, 27]
for a, b in zip(listA, listB):
print(a, b)
# 'a', 3
# 'b', 5
# 'c', 7
여기서 조금만 더 어려운 이야기를 하자면, for문을 이용해 리스트를 돌 때 해당 값을 수정해도 리스트에 반영되지 않습니다.
list_a = [2, 4, 6, 10, 12]
for a in list_a:
a = 7
print(a)
print(list_a)
위 코드를 실행해도 print(a)에선 7이 출력되지만 list_a의 요소 값들에 반영되지는 않습니다. 왜냐하면 위 코드에서 변수 a는 리스트의 값을 가리키는 것이 아니라 그 값을 그대로 복사해온 것이기 때문입니다. 즉, 변수 a는 list_a의 요소와 같은 값을 갖기는 하지만 list_a의 요소 자체를 가리키는 것은 아니라는 겁니다.
만약 리스트의 요소값들을 수정하고 싶다면 인덱스를 이용해 직접 리스트의 값에 접근해야 합니다.
list_a = [1, 2, 3]
for i, a in enumerate(list_a):
list_a[i] = a + 1
# [2, 3, 4]
위와 같이 리스트의 인덱스를 이용해 해당 값에 직접 접근해야 값들을 수정할 수 있습니다.
for문도 while문과 같이 break를 이용해 반복을 중간에 종료할 수 있습니다. 이제 for문에 대해서 좀 알겠나요?
2.3. 이중 반복문
반복문도 이중, 삼중으로 반복할 수 있습니다. 보통 좌표계를 나타내거나 이중 배열 등에 사용됩니다.
img_a = [[1, 2, 3],
[11, 12, 13],
[21, 22, 23]]
for line in img_a:
print(line)
for a in line:
print(a)
# [1, 2, 3]
# 1
# 2
# 3
# [11, 12, 13]
# 11
# 12
# 13
# [21, 22, 23]
# 21
# 22
# 23
만약 이런 이중 반복문에서 break를 사용할 경우, 해당 break가 속하는 하나의 반복문에만 적용됩니다. 예를 들면,
for i in range(5):
print("i :", i)
for j in range(3):
print(" j :", j)
if j == 1:
break
위 코드를 실행하면 j가 1이 될 때 break가 걸리지만, 해당 break를 포함하는 for j in range(3): 반복문만 종료되지 for i in range(5): 반복문은 그대로 진행된다는 것을 알 수 있습니다.
이렇게 조건문과 반복문에 대해 알아봤습니다. 처음 코딩을 공부하는 입장에서 특히 반복문은 많이 헷갈리는 요소일 겁니다. 익숙해지고 잘 다루는 방법은 많이 써보는 것밖에 없습니다... 반복문을 활용하는 간단한 코딩 문제를 풀어보거나 직접 다양하게 활용해 보는 방식으로 익숙해지는 것을 추천 드립니다.
https://www.acmicpc.net/step/3
위 사이트 링크는 백준 프로그래밍 사이트로 코딩테스트를 연습하는 사이트지만 기초적인 코딩 연습 문제들도 있으니 연습해 보시기 바랍니다.
너무 감이 안 온다 싶으면 제가 낸 예제 3개와 정답 코드를 보면서 이해도를 더 높이셔도 좋을 것 같습니다.
https://all-the-meaning.tistory.com/53
풀이까지 자세히 설명했기 때문에 도움이 되셨으면 좋겠습니다. 감사합니다.