본문 바로가기
Python/파이썬 알고리즘

[파이썬 알고리즘 #4] 조건문

by 서원두 2022. 8. 4.

이번엔 조건문에 대해서 다뤄보고자 한다. PS에 도움 되는 스킬도 적어보고자 한다.

 


조건문은 무엇인가?

간단히 말해, 특정 조건을 만족할 때에 추가로 실행하고 싶은 것을 돌리게 하는 일종의 트리거 장치다.

조건 $ A $의 경우엔 실행문 $ a $의 절차를 밟아야 하고, 조건 $ B $의 경우엔 실행문 $ b $로 돌려야 할 때 쓰인다.

이때 필요한 구문은 if - else문이다. 조건문이 참이냐 거짓이냐에 따라서 로직을 나누게 해 준다.

 

예시 : [BOJ] 1330번 두 수 비교하기

이 문제가 매우 정석적인 if - else문을 쓰는 문제다. a와 b 크기를 구분하는 아주 쉬운 문제다.

if a > b:
    print('>')
elif a < b:
    print('<')
else:
    print('==')

 

a가 b보다 크면 >를 출력하고(if문), b가 a보다 크면 <를 출력하고(elif문), a와 b가 같다면 ==을 출력한다(else문).

이 문제의 핵심은 if문의 조건이 elif문이나 else문 등지에서 실행되지 않는다는 것이다.

즉, 위의 예시에서는 '<', '>', '==' 중에서 하나를 출력할 때에는 그 하나만 출력하고 그대로 if - else문이 종료된다는 뜻이다.


아래의 예시를 보자. 참고로 아래의 예시는 위의 문제와 일절 연관이 없다.

if a > b:
    print('>')
        
if a >= b:
    print('>=')

 

이 코드에서 만약 $ a=4 $, $ b=3 $이라면 결과는 어떻게 될까?

# Result
>
>=

 

if문이 두 개이기 때문에 결과가 둘 다 나온다. 두 조건 전부 만족하기 때문이다.

즉, if문은 조건문이 참인지 거짓인지를 판별하고 그에 따른 결과를 내놓는 것이다.

조건문의 구조는 아래와 같다고 보면 된다.

조건문과 그 안의 구조는 이렇다

조건문끼리는 다른 세상이고, 조건문 안에는 if - else문을 얼마만큼 나누냐에 따라 그만큼 조건문 안의 세상을 구분시킬 수 있다. 그리고 그 구분된 공간은 다른 공간과 중복되지 않는다.

이 부분을 잘 이해하고 넘어간다면 정말 많은 코드들을 원하는 대로 짜기 수월해진다.

 

조건문을 대충 짜게 되면 생기는 문제

대표적인 조건문 밈

아내의 말을 조건문으로 옮기면 아래와 같다.

buy one jug of milk
if there is avocado:
    get six avocados

 

반면 남편이 알아들은 말을 조건문으로 옮기면 아래와 같다.

buy one jug of milk
if there is avocado:
    get six jugs of milk

 

웃기게도, 원래는 7개를 사와야 맞는 밈이 되는데 사진에는 6개뿐이다. 이 또한 조건을 애매한 말로 정해서 그런 것이다.

애매한 말로 두 개의 조건문이 나오는 유명한 밈이다. 조건문을 대충 쓰는 그 즉시 피를 크게 보니 잘 생각해서 사용하자.

 

조건문을 파이썬에서 쓰기

PS에서는 조건문에 주로 비교 연산자인 NOT($ \neg $), AND($ \land $), OR($ \lor $)와 비교 연산자인 <(=), >(=), ==, !=가 쓰인다. 사실 PS가 아닌 일반적인 경우에서도 쓰이는 건 비슷비슷하다.

다들 알다시피 NOT은 조건문에 부정을 붙이며, AND는 연산할 조건문들이 전부 참일 때에만 참이며 나머지는 거짓을 반환하는 연산자, OR는 전부 거짓일 때만 거짓이고 나머진 참을 주는 연산자다.

이 부분에 대해서 더 자세히 알고 싶다면 이산구조를 배우면 된다. 이산구조에서는 조건문 이외에도 컴퓨터공학적인 부분을 더 알려주며, DP의 기초인 점화식, 빅오 표기법($ O(N) $ 같이 생긴 것이 빅오 표기법이다), 그래프 그리고 트리까지 이론적으로 배울 수 있다. 굉장히 중요한 전공 기초 과목이며, 재밌고 유익할 것이다. 추천하는 책은 Rosen의 Discrete Mathematics and Its Applications이다.

A와 B라는 조건문(또는 변수)이 있다고 치자. 이를 파이썬에서 조건문으로 쓰는 법은 아래와 같다.

# A라면
if A:

# A가 아니라면
if !A:
if not A:

# A 또는 B라면
if A or B:

# A 그리고 B라면
if A and B:

# A와 B가 같다면
if A == B:

# A가 B와 다르다면
if A != B:

 

이 부분은 쉽다. 이와 관련하여 쉽고 좋은 문제를 남긴다.

 

심화 : 쇼트 서킷(short circuit)

쇼트 서킷(short circuit) 트릭에 대해서 알려주고자 한다. 조건문에서 자주 써먹는 트릭이다.

예를 들어 아주 많은 조건문에 대해 OR과 AND 연산을 한다고 하자.

OR은 모든 조건문 중에서 하나만이라도 참이면 참을 주고, AND는 반대로 하나만이라도 거짓이면 거짓을 준다.

쇼트 서킷의 핵심은, OR에서는 가장 참일 확률이 높은 조건문을, AND에서는 가장 거짓일 확률이 높은 조건문을 먼저 써주는 것이다.

조건문이 많으면 많을수록 모든 조건문을 돌아야 한다. 이는 실행시간에 약간의 지장을 준다.

그래서 순서를 살짝 조정하는 것이다. 어차피 컴퓨터는 조건문을 처음부터 하나씩 판단하기 때문이다.

조건문을 판단하다가 위의 상황이 나오는 그 즉시 조건문 판단을 멈추고 다음 행동으로 넘어가게 해 준다.

예시를 들자. OR문을 작성하는데, 조건문 A가 참일 확률이 가장 높고 알파벳 순으로 그 확률이 떨어진다고 하자.

그렇다면 아래와 같이 작성하면 실행 속도는 매우 빨라질 것이다.

if A or B or C or ... or X or Y or Z:
    # Do something

 

조건문 중 하나만 참이어도 참인 OR문의 특성을 잘 쓴 코드다.


다만 쇼트 서킷이 항상 좋은 것은 아니다. 순서대로 판정하는 조건문 중 하나만이라도 참/거짓인 경우에 실행문으로 넘어가기 때문에 다른 조건문을 체크하지 않는 단점도 존재한다.

이게 무슨 소리인지 알기 위해 예시를 들자.

앞으로 여러분이 문제를 풀 때 list의 크기를 굉장히 많이 따질 것이다. 이 조건문을 OR문 또는 AND문에 순서에 집중하지 않고 넣는다면 피를 볼 수 있다는 뜻이다.

now_list의 가장 마지막 두 요소를 이용한 연산이 들어간 조건문이 A, now_list의 요소 개수가 두 개 이상이라는 조건문이 B일 경우의 코드를 아래와 같이 짜보자.

now_list = list()

if now_list[-1] + now_list[-2] > 0 and len(now_list) >= 2:
    # Do something
    
# → ERROR!!!

 

위와 같이 A and B로 코딩하는 순간 에러가 난다. A는 now_list의 요소에 접근해야하는 조건문인데 now_list가 비어있기 때문에 에러를 뱉는다.

now_list = list()

if len(now_list) >= 2 and now_list[-1] + now_list[-2] > 0:
    # Do something
    
# → OK

 

반대로 B and A로 설정하면 에러가 나지 않는다. now_list의 길이는 0이라 거짓이고, AND문으로 엮여있기 때문에 처음으로 쓰인 조건문 B만 보고 바로 거짓이라 판단하고 조건문을 빠져나온다. 첫번째 조건문이 거짓이므로 굳이 두 번째로 쓰인 조건문 A를 판정하지 않는다.

이 트릭을 써서 수월하게 풀 수 있는 문제들이 꽤 있기 때문에 조건문 순서를 잘 둬야한다.

 

심화 : 파이썬으로 조건문 더 알차게 쓰기

파이썬에서 조건문에는 단순히 변수만 집어 넣어도 작동한다!

가장 먼저 변수를 예로 들자.

if __name__ == '__main__':
    a = 1
    if a:
        print(a)
    else:
        print('No a')
        
    b = 0
    if b:
        print(b)
    else:
        print('No b')
        
    c = -1
    if c:
        print(c)
    else:
        print('No c')

 

# Result
1
No b
-1

 

변수의 경우, 0일 경우엔 거짓이 되지만 다른 모든 수에 대해서는 참이 된다.

이를 이용한 다른 좋은 예시는 리스트(list)다.

if __name__ == '__main__':
    a = []
    if a:
        print(a)
    else:
    	print('No a')

    b = [1]
    if b:
        print(b)
    else:
    	print('No b')

 

# Result
No a
[1]

 

리스트의 경우, 비어있으면 거짓이 되고 하나라도 들어있으면 참이 된다.

이를 이용한 트릭을 파이썬에서 자주 쓰므로 꼭 기억해두는 것이 좋다.


 

조건문은 쉽기 때문에 이 정도면 충분하다고 생각한다.

728x90

댓글