파이썬 제어문과 반복문

제어구문이란?

제어 구문이란 입력이나 출력 등 어떤 값에 의해서 프로그램의 흐름을 바꿀 수 있는 명령어를 의미합니다. 쉽게 말하면 프로그램의 흐름이 코딩 순서대로 흘러가다가 어떤 조건(Condition)에 의해서 프로그램의 흐름이 달라지는 것을 의미합니다. 실제로 이런 일은 프로그램을 하면서 매우 자연스러운 것입니다.

이런 조건문을 말로 풀어 본다면 “만일 000 라면 000 하라” 라고 쓸 수 있습니다. 이 안에 여러가지를 넣어서 문장을 만들 수 있습니다. “만일 성적이 90점 이상이라면 A를 주어라” 라고 한다면 입력되는 점수에 따라서 그 성적이 바뀔 수 있을 것입니다. 조건을 하나 더 붙인다면 “만일 90점 이상이라면 A를 주고 80점 이상이라면 B를 주고 70점 이상이라면 C를 주고 60점 이상이라면 D를 주고 그 이하라면 F를 주어라” 라고 조건을 여러개 주어서 프로그램을 만들 수도 있습니다.

IF 조건문

파이썬에서 이런 조건에 따라서 수행할 코드를 분기 할때에 사용하는 것이 if 조건문입니다. if 조건문은 굉장히 간단한 구조로 되어 있기 때문에 쉽게 이해하고 사용할 수 있습니다.

if 조건식:
    # 조건식이 참(True)일 경우에 실행
else:
    # 조건식이 거짓(False)일 경우에 실행

if 조건문에 들어가는 조건식에는 주로 하나 이상의 변수를 사용해서 조건식을 만듭니다. 예를 들어서 하나의 조건문이 True/False 인지를 확인할 수 있고 두개의 변수를 서로 비교해서 같거나 다르거나 크거나 같거나를 표현 할 수도 있습니다.
그것을 정리하면 아래의 표와 같습니다.

a == b # 두개의 변수 a와 b가 같다. 맞으면 True 틀리면 False
a != b # 두개의 변수 a와 b는 같지 않다. 
a > b  # 두개의 변수 a는 b보다 크다.
a >= b  # 두개의 변수 a는 b보다 크거나 같다.
a < b # 두개의 변수 a는 b보다 작다.
a <= b # 두개의 변수 a는 b보다 작거나 같다.

이 두개의 변수는 숫자값이 들어가도 되지만 문자열도 입력할 수 있습니다. 문자열의 경우에는 문자의 비교만 가능합니다. 예를 들어서 a=”apple”, b=”pear” 일때 a == b 조건은 당연히 False가 됩니다. 이런 방법으로 문자가 같은지를 확인하는 조건식을 만들고 활용할 수 있습니다.
주의 해야 할 것은 a와 b가 같은지를 볼때에 ‘=’ 하나를 쓰는 것이 아니라 ‘==’ double equal을 사용한다는 것입니다. 하나만 사용할 경우에는 해당 변수에 값을 대입하는 것으로 인식하기 때문에 조건문을 사용할 때에 이 부분을 조심하셔야 합니다.

이 조건문을 사용해서 이전에 간단히 설명했던 성적코드를 표시하는 프로그램을 작성해보면 아래와 같이 할 수 있습니다. 여기서 보면 “if 조건문 elif 조건문 else…”의 형태가 나오는데 여기서 나오는 “elif”는 새로운 것이 아니라 “else if”의 축약된 형태로 조건문이 False일 경우에 다른 조건문을 사용하는 간단히 말하면 중첩된 조건문에서 사용하는 코드입니다. “if … elif…”를 사용하지 않고 “if … else …” 형태를 반복해서 사용할 수 있지만 이렇게 작성된 코드는 코딩이 길어지기 때문에 간결하지 않고 또 간결하지 않은 코드는 수정이 쉽지 않다는 단점이 있습니다.

그렇기 때문에 가급적이면 간단하게 코딩하는 습관을 기르는 것이 좋습니다.

score = 88

if score > 90:
    print('A')
elif score > 80:
    print('B')
elif score > 70:
    print('C')
elif score > 60:
    print('D')
else:
    print('F')

위의 코드를 실행하면 출력값은 ‘B’가 출력됩니다.

아래의 코드는 문자열 값을 입력해서 비교하는 코드입니다. 아래와 같은 경우는 출력값이 False가 됩니다.

a = "apple"
b="pear"

if a == b:
    print('True')
else:
    print('False')

그리고 비교하는 변수는 꼭 두개가 있어야 하는 것은 아닙니다. 아래와 같이 flag를 bool 자료형으로 선언하고 True 값을 주면 해당 값의 조건에 따라서 True / False를 출력합니다.

flag = True

if flag:
    print('True')
else:
    print('False')

또 아래와 같이 조건식을 여러개 함께 사용할 수도 있습니다. 그렇게 되면 이전에 논리연산자를 함께 사용해야 합니다. 논리 연산자는 ‘and’,’or’ 연산자입니다. ‘and’의 경우에는 조건 모두를 만족해야 참(True)이고 하나라도 만족하지 않으면 거짓(False)가 됩니다. 그러나 ‘or’의 경우에는 조건 중 하나만 만족해도 참(True)이 됩니다.

아래의 조건문의 경우에는 a==b가 False이지만 score > 80이 True 임으로 출력값은 True를 표시하게됩니다.

if (a==b) or score > 80:
    print('True')
else:
    print('False')

반복문

제어문과 마치 한쌍과 같이 사용되는 것이 바로 반복문입니다. 이 반복문은 리스트와 같은 어떤 연속된 자료를 반복해서 처리하면서 사전에 정의된 조건문을 처리합니다. 가장 많이 사용되는 반복문은 for나 while과 같은 명령어입니다. 이 두 반복문에도 역시 반복에 필요한 조건들이 들어갑니다.

만약 조건이 들어가지 않는다면 해당 반복문들은 무한히 명령어를 실행하게됩니다. 이것을 무한루프라고 합니다. 시스템이 무한루프에 들어가면 무한정 리소스를 사용하기 때문에 결국 응용프로그램이 에러를 출력하게됩니다.

WHILE 루프

while은 for 루프와 함께 파이썬의 대표적인 반목문입니다. 어떤 조건을 주고 그 조건이 참일때까지 해당 명령어를 수행하게됩니다. 아래의 예와 같이 사용하는 방법도 굉장히 간단합니다.

while 조건식:
    #반복하면서 처리할 코드

이제 while 루프를 사용해서 간단한 코딩을 해보겠습니다. 일단 score라는 리스트를 선언하고 해당 리스트에 성적을 입력합니다. 그리고 리스트의 크기만큼 루프를 반복하며 성적을 출력해보는 예제입니다. 여기서 len() 함수는 리스트의 크기를 리턴해줍니다. 그러므로 아래의 예제는 i라는 변수에 0을 입력하고 i가 리스트의 크기보다 작은 조건을 만족할 때까지 while 루프안에 있는 print 구문을 수행하고 i의 값에 1을 계속적으로 더해줍니다. 결국 i는 0-4까지의 조건을 만족하겠고 5가 되는 순간 리스트의 크기와 같아지면서 해당 조건을 만족하지 않기 때문에 while 루프에서 벗어나게 됩니다.

실제로 아래 예제를 수행해보면 100부터 87까지의 값을 출력하고 해당 루프를 빠져나가는 것을 확인할 수 있습니다.

score = [100,80,99,92,87]
i = 0
while i < len(score):
    print(score[i])
    i += 1

만약 while의 조건식 부분에 True를 입력하게 되면 어떻게 될까요?
해당 구문은 무한루프로 들어가게됩니다. 언제 이런 구문을 사용하는가 생각해보면 사용자가 값을 계속 입력하는 상황을 생각해 볼 수 있겠습니다. 그러다가 마지막으로 입력을 종료하고 싶으면 약속된 키를 입력하면 종료되는 상황이 있을 수 있습니다.

my_score = []
while True:
    s = input('Score?')
    if s == 'q': break
    my_score.append(s)

print('입력하신 스코어는 {}입니다.'.format(','.join(my_score)))

::: 출력 형태 :::
Score? 100
Score? 90
Score? 50
Score? 60
Score? 80
Score? q
입력하신 스코어는 100,90,50,60,80입니다.

해당 코드를 실행하면 위와 같이 q라는 값이 들어오기 전까지 while 안에 있는 명령어를 계속 실행하게 되고 q 값이 입력되면 break 문이 실행되면서 while 루프를 벗어나게 됩니다. 만약 break 문이 없다면 해당 코드를 강제로 종료해야 하는 일이 생기게됩니다.

FOR 루프

for 루프는 while과 함께 대표적인 반복문입니다. while 루프도 많이 사용하지만 아마도 가장 많이 사용하는 것이 for 문법이라고 생각합니다. for는 사용하기가 while 비해서는 약간 복잡하게 느껴질 수도 있지만 다양한 표현이 가능하다는 것은 많은 부분에서 사용할 수 있다는 의미도 됩니다.

몇가지 예제를 통해서 그 쓰임을 알아보겠습니다.

for 루프 변수 in 리스트(또는 튜플, 문자열):
    # 수행할 명령어
    ...

위의 문법을 보면 for 다음에는 ‘루프 변수’가 입력됩니다. ‘루프 변수’는 쉽게 말해서 in 다음에 표시되는 리스트(또는 튜블, 문자열)의 내용을 담아내는 변수입니다. 다시 말하면 for 루프는 리스트의 크기 만큼 실행되며 리스트의 갯수 하나씩 루프 변수에 담는다는 의미입니다. 말로 풀어서 쓰면 복잡하지만 실제로 사용하는 것은 굉장히 간단하고 직관적입니다.

# case1 숫자 리스트
score = [100,80,99,92,87]
for s in score:
    print(s)

# case2 문자열
message = "Hello, World!"
for c in message:
    print(c)

# case3 범위
for i in range(10):
    print(i)

위의 코드를 실행해보면 case1은 score안에 있는 점수가 하나씩 출력됩니다. case2는 message에 입력된 문자열 데이터가 한글자씩 표시됩니다. case3를 실행해보면 0-9까지의 숫자가 출력됩니다.

여기에서 사용하는 range() 문은 굉장히 많이 사용하는 파이썬 내장함수이기 때문에 좀 더 알아보면 방금 사용했던것처럼 range(10)이라고 하면 0-9까지를 출력하고 range(5,10)으로 선언하면 시작하는 숫자가 5부터 시작하니 5-9까지를 출력하게됩니다. range(0,10,2)로 표시하면 0-9까지 2씩 증가한 값 즉, 0,2,4,6,8을 표시하게됩니다.

이 외에도 앞서 살펴본 while에서 break 문도 역시 for에서 사용할 수 있고 또 continue 문도 사용할 수 있습니다. break 문은 앞서 보았기 때문에 이번에는 continue 문을 어떻게 사용하는지 보겠습니다.

5개의 과목 중에서 90점이 넘는 과목은 A로 표시한다고 하면 아래와 같이 continue를 사용해서 표현할 수 있습니다. 조건을 만족하면 조건문 아래 라인을 실행하지 않고 조건을 만족하지 않으면 아래 라인을 실행하게 됩니다. break문의 경우에는 조건을 만족하면 for문을 빠져나가는데 이와 비슷한 개념이지만 약간의 차이가 있습니다.

# case1 숫자 리스트
score = [100,80,99,92,87]
for s in score:
    if s <= 90:
        continue
    print('{}점은 A입니다.'.format(s))

또 하나 파이썬에서 사용하는 for문의 독특하면서도 강력한 기능 중에 하나는 for 문을 한줄로 나열해서 쓸 수 있다는 것입니다. 이것도 예제를 통해서 살펴보겠습니다.

점수를 가지는 하나의 배열이 있는데 이 배열은 2개의 차원으로 되어있다고 가정합니다.

array2d[0] 번지에는 [100,99,98]의 값이 저장되어 있습니다.
array2d[1] 번지에는 [99,78,89] 값이 저장되어 있습니다.
array2d[2] 번지에는 [98,88,91] 값이 저장되어 있습니다.

이 배열에서 해당 점수를 표시하려면 위의 경우와 같이 ‘for s in array2d’와 같은 형식으로도 사용할 수 있지만 아래와 같이 그냥 한줄로 표시할 수도 있습니다.

array2d = [[100,99,98], [99,78,89], [98,88,91]]
['socre:{},{},{}'.format(arr[0],arr[1],arr[2]) for arr in array2d]

이러한 표현 방법은 numpy이나 pytorch에서 여러 줄의 코드를 간단히 한줄로 표현할 수 있게 해주는 굉장히 유용한 방식입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다