7. 조건문#

특정 조건의 성립여부에 따라 다른 코드를 실행하게 만드는 명령문이다. 조건문을 이용하여 보다 다양한 기능을 갖는 프로그램을 구현할 수 있다.

7.1. if ... else ... 명령문#

조건문conditional statement의 일반적인 형식은 다음과 같다.

if 논리식:
    명령문1
else:
    명령문2
  • 명령문1: 논리식이 참일 때 실행

  • 명령문2: 논리식이 거짓일 때 실행

예를 들어 아래 코드는 실행되는 순간 변수 x가 가리키는 값이 0보다 작으면 'x는 음수'가, 그렇지 않으면 'x는 음수 아님'이 화면에 출력된다.

x = -1

if x < 0:
    print('x는 음수')
else:
    print('x는 음수 아님')    
x는 음수

else 키워드 부분을 사용하지 않아도 된다. 아래 코드에서 변수 x가 가리키는 값이 0보다 작을 때 'x는 음수'가 출력된다.

x = -1

if x < 0:
    print('x는 음수')
    
print("음수만 처리합니다.")
x는 음수
음수만 처리합니다.

변수 x가 가리키는 값이 0보다 같거나 큰 경우는 무시된다.

x = 2

if x < 0:
    print('x는 음수')
    
print("음수만 처리합니다.")
음수만 처리합니다.

7.2. 논리식#

조건문의 헤더headerif 키워드와 참 또는 거짓을 가리키는 논리식으로 구성된다. 예를 들어, 두 표현식의 등가 여부를 판단하는 연산자 ==를 이용한 논리식은 다음과 같다.

  • 참인 등가 논리식

5 == 4 + 1
True
  • 거짓인 등가 논리식

3 + 2 ==  3 * 2
False

두 표현식이 서로 다른 값을 가리키는지 여부를 판단하는 연산자는 !=이며, == 와 반대로 작동한다.

5 != 4 + 1
False
3 + 2 !=  3 * 2
True

7.2.1. bool 유형#

논리식이 표현하는 값은 TrueFalse 중에 하나이며, 이 두 값으로만 구성된 자료형을 부울 자료형이라 부르며, bool이 부울 자료형을 가리킨다.

type(True)
bool
type(False)
bool
type(5 == 4 + 1)
bool
type(3 + 2 !=  3 * 2)
bool

7.2.2. 비교 연산자#

논리식은 기본적으로 등식, 부등식 등의 비교 연산자를 이용하여 표현하며, 논리 연산자를 이용하여 보다 복잡한 논리식을 구성한다.

비교 연산자는 수, 문자열 등의 크기를 비교할 수 있으며 대표적인 비교 연산자는 아래와 같다.

연산 기호

의미

예시

실행 결과

<

작다

2 < 1

False

<=

작거나 같다

1 <= 2

True

>

크다

2 > 1

True

>=

크거나 같다

1 >= 2

False

==

같다

3 == 2 * 1

False

!=

같지 않다

1 != '1'

True

자료형이 다른 두 값에 대해서 == 연산자는 기본적으로 거짓으로 판정한다.

1.0 == '1.0'
False

하지만 정수는 부동소수점으로 취급하기에 예를 들어 1과 1.0은 등가라고 판정한다.

1 == 1.0
True

문자열 비교 연산자

문자열도 비교 연산자를 지원하며 알파벳 순서를 따르는 순서 개념을 사용한다.

'apple' < 'banana'
True

영어 알파벳의 경우 대문자가 소문자보다 작다고 판단한다.

'apple' < 'Apple'
False

7.2.3. 논리 연산자#

영어의 and, or, not 의 개념과 거의(!) 유사하게 작동하는 세 개의 논리 연산자를 이용하여 보다 복잡한 논리식을 구현할 수 있다.

  • A and B: AB 모두 참일 때만 참으로 판정됨

  • A or B: A가 참이거나 A가 거짓일 때 B가 참이면 참으로 판정됨

  • not A: A 가 거짓일 때만 참

연산 기호

의미

예시

실행 결과

and

그리고

1==2 and 3==2+1

False

or

또는

1==2 and 3==2+1

True

not

부정

not 1==2

True

우선 순위

논리 연산자들 사이의 우선순위는 not, and, or 순으로 높다.

  • 예제 1

not a > b and b > c

(not a > b) and b > c

와는 서로 등가이지만

not (a > b and b > c)

와는 아래 예제에서 볼 수 있듯이 서로 다른 값을 표현한다.

a = -23
b = -7
c = 1

print(not a > b and b > c)
print((not a > b) and b > c)
print(not (a > b and b > c))
False
False
True
  • 예제 2

a > b and b > c or c < d

(a > b and b > c) or c < d

와는 서로 등가이지만

a > b and (b > c or c < d)

와는 그렇지 않다.

a = -23
b = -7
c = 1
d = 28

print(a > b and b > c or c < d)
print((a > b and b > c) or c < d)
print(a > b and (b > c or c < d))
True
True
False
  • 예제 3

a > b or b > c and c < d

a > b or (b > c and c < d)

와는 서로 등가이지만

(a > b or b > c) and c < d)

와는 그렇지 않다.

a = -2
b = -7
c = 1
d = 0

print(a > b or b > c and c < d)
print(a > b or (b > c and c < d))
print((a > b or b > c) and c < d)
True
True
False

bool() 형변환 함수

bool() 함수는 인자의 상태에 따라 True 또는 False를 반환한다. 예를 들어, 0이 아닌 수는 참, 0은 거짓으로 처리된다.

bool(0)
False
bool(0.0)
False
bool(17.1)
True

None, 빈 문자열, 빈 리스트 또한 거짓으로 간주된다.

bool(None)
False
bool('')
False
bool([])
False

0, None, 빈 리스트와는 달리 무언가 있다는 것을 나타내는 값은 모두 참으로 간주된다.

bool([1])
True
bool('abc')
True

그런데 정수, 리스트, 문자열 등을 논리식에 사용할 때 bool() 형변환 함수를 사용하지 않아도 된다. 이유는 마치 bool() 형변환 함수가 적용된 것처럼 처리되기 때문이다.

1 and False
False
0 or True
True
[1] and (1 < 0)
False
None or (1 < 0)
False

andor 연산자

andor 두 연산자는 영어 단어 andor 와는 조금 다르게 작동한다. 예를 들어, 아래와 같이 False and 3/0를 실행하면 False로 계산되는데 좀 이상하다. 왜냐하면 3/0ZeroDivisionError 라는 오류를 발생시켜야 할 것으로 기대되기 때문이다.

False and 3/0
False

실제로 3/0 and False 를 실행하면 3/0을 먼저 확인하기에 오류가 발생한다.

3/0 and False
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[34], line 1
----> 1 3/0 and False

ZeroDivisionError: division by zero

False and 3/0 를 실행할 때 오류가 발생하지 않은 이유는 x and y에서 x가 참일 때만 y 를 확인하기 때문이다. 따라서 만약 x가 거짓으로 판명되면 논리식 전체를 바로 거짓으로 계산한다. 즉, x and yx가 거짓일 때만 y를 확인하는데 False and 3/0에서 and 연산자의 첫째 인자가 False 이기에 둘째 인자인 3/0의 참, 거짓 여부는 아예 확인하지 않는다.

아래 코드는 or 연산자도 영어 단어 _or_와 조금 다르게 작동함을 보여준다.

True or 3/0
True

반면에 아래 코드를 실행하면 오류가 발생한다.

3/0 or True
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[53], line 1
----> 1 3/0 or True

ZeroDivisionError: division by zero

True or 3/0 를 실행할 때 오류가 발생하지 않은 이유는 x or y에서 x가 거짓일 때만 y 를 확인하기 때문이다. 따라서 만약 x가 참으로 판명되면 논리식 전체를 바로 참으로 계산한다. 즉, x or yx가 거짓일 때만 y를 확인하는데 True or 3/0에서 or 연산자의 첫째 인자가 True 이기에 둘째 인자인 3/0의 참, 거짓 여부는 아예 확인하지 않는다.

7.3. if ... elif ... else ... 명령문#

참, 거짓 여부를 판단해야 하는 경우가 세 개 이상일 때 조건문에 elif 키워드를 추가로 사용한다. 예를 들어 아래 코드는 xy의 크기 비교를 위해 작을 때, 클 때, 같을 때 세 가지 경우로 판단한다.

x = -2
y = 3

if x < y:
    print('x가 y보다 작다')
elif x > y:
    print('x가 y보다 크다')
else:
    print('x와 y가 같다')
x가 y보다 작다

elif는 영어의 ‘’else if’’의 줄임말이며, 사용하는 경우의 수 만큼 사용될 수 있다. ifelif 문에 사용된 조건은 위에서부터 차례대로 확인되어 참이되는 경우의 명령문이 실행되며 그러면 나머지 경우는 무시된다. 따라서 위 코드의 조건문이 나타내는 세 가지 경우는 다음과 같다.

  • x < y가 참인 경우

  • x < y가 거짓이면서 x > y가 참인 경우

  • x < yx > y 모두 거짓인 경우, 즉 x == y 가 참인 경우

이처럼 if ... elif ... else ... 에 사용된 논리식은 항상 이전의 논리식이 거짓임을 가정한다.

예제

아래 코드는 y를 5로 나눈 나머지에 따라 다른 명령문을 다음과 같이 지정할 수 있다.

y = 4
x = y % 5

if x == 0:
    print('나머지가 0')
elif x == 1:
    print('나머지가 1')
elif x == 2:
    print('나머지가 2')
elif x == 3:
    print('나머지가 3')
else:
    print('나머지가 4')
나머지가 4

else는 이전에 사용된 모든 논리식이 거짓일 때 실행할 명령문을 지정하며 불필요할 경우 생략이 가능하다. 위 코드에서 사용된 else 대신에 아래 코드에서철 elif를 한 번 더 써도 동일한 결과가 나온다.

y = 4
x = y % 5

if x == 0:
    print('나머지가 0')
elif x == 1:
    print('나머지가 1')
elif x == 2:
    print('나머지가 2')
elif x == 3:
    print('나머지가 3')
elif x == 4:
    print('나머지가 4')
나머지가 4

예제

주어진 세 개의 정수 a, b, c중에서 최댓값을 확인하려면 아래처럼 세 수를 비교해서 나머지 두 수보다 큰 값을 최댓값으로 정한다.

  • abc 모두 보다 같거나 큰 경우: a가 최댓값

  • bac 모두 보다 같거나 큰 경우: b가 최댓값

  • cab 모두 보다 같거나 큰 경우: c가 최댓값

a = 3
b = 7
c = 10

if a >= b and a >= c:
    print("최댓값:", a)
elif b >= a and b >= c:
    print("최댓값:", b)
elif c >= a and c >= b:
    print("최댓값:", c)
최댓값: 10

그런데 위 코드에서 마지막 elif 명령문을 else로 대체해도 된다.

a = 3
b = 7
c = 10

if a >= b and a >= c:
    print("최댓값:", a)
elif b >= a and b >= c:
    print("최댓값:", b)
else:
    print("최댓값:", c)
최댓값: 10

실제로 a >= b and a >= cb >= a and b >= c 모두 거짓인 경우 a, b 모두 c 보다 작다. 이유는 필수 예제를 참고한다.

7.4. 논리 연산자와 중첩 조건문#

elif 키워드는 사실 없어도 된다. 예를 들어 아래 코드는 주어진 두 값을 비교할 때 크거나, 작거나, 또는 같다의 세 경우를 다음과 같이 구분해서 처리한다.

  • if: x < y가 참인 경우 처리

  • else: x < y가 거짓인 경우. 따라서 x > yx == y 두 경우를 처리해야 함.

    • if: x < y가 거짓이라는 전제 하에 x > y가 참인 경우 처리

    • else: x < y가 거짓이라는 전제 하에 x == y가 참인 경우 처리

x = -2
y = 3

if x < y:
    print('x가 y보다 작다')
else:
    if x > y:
        print('x가 y보다 크다')
    else:
        print('x와 y가 같다')
x가 y보다 작다

그런데 많은 경우 논리 연산자를 활용하면 중첩 조건문을 굳이 사용하지 않아도 된다. 예를 들어 아래 코드는 중첩 조건문을 사용하여 x가 0보다 크면서 동시에 10보다 작은 경우를 다룬다.

x = 3

if 0 < x:
    if x < 10:
        print('x가 0보다 크고 동시에 10보다 작다.')
x가 0보다 크고 동시에 10보다 작다.

print() 함수가 0 < xx < 10 두 조건을 모두 만족하는 경우에만 실행되기에 아래와 같이 and 연산자를 이용할 수 있다.

x = 3

if 0 < x and x < 10:
    print('x가 0보다 크고 동시에 10보다 작다.')
x가 0보다 크고 동시에 10보다 작다.

참고로 0 < x and x < 100 < x < 10로 표현할 수 있다.

x = 3

if 0 < x < 10:
    print('x가 0보다 크고 동시에 10보다 작다.')
x가 0보다 크고 동시에 10보다 작다.

7.5. 필수 예제#

참고: (필수 예제) 조건문

7.6. 연습문제#

참고: (실습) 조건문