2014년 1월 20일 월요일

파이썬 제어문 - IF문

다음과 같은 상상을 해 보자.
"돈이 있으면 택시를 타고 가고 돈이 없으면 걸어 간다."
위와 같은 상황은 우리 주변에서 언제든지 일어 날 수 있는 상황중의 하나이다. 프로그래밍이란 것도 사람이 만드는 것이라서 위와 같은 문장처럼 조건을 판단해서 그 상황에 맞게 처리해야 할 경우가 생기게 된다. 이렇듯 조건을 판단하여 해당 조건에 맞는 상황을 수행하는데 쓰이는 것이 바로 if문이다.
위와 같은 상황을 파이썬에서는 다음과 같이 만들 수 있다.
>>> money = 1
>>> if money:
...     print("택시를 타고 가라")
... else:
...     print("걸어가라")
...
택시를 타고 가라

if문의 기본 구조

다음의 구조가 if와 else를 이용한 기본적인 구조이다.
if <조건문>:
    <수행할 문장1>
    <수행할 문장2>
    ...
else:
    <수행할 문장A>
    <수행할 문장B>
    ...
조건문을 테스트 해서 참이면 if문 바로 다음의 문장들을 수행하고 조건문이 거짓이면 else문 다음의 문장들을 수행하게 된다.

들여쓰기(indentation)

if 문을 만들 때는 다음 처럼 if <조건문>: 다음의 문장부터 if문에 속하는 모든 문장들에 들여쓰기를 해 주어야 한다.
if <조건문>:
    <수행할 문장1>
    <수행할 문장2>
    <수행할 문장3>
위에서 보는 것과 같이 조건문이 참일 경우 <수행할 문장1>을 들여쓰기 하였고 <수행할 문장2><수행할 문장3>도 들여쓰기를 해 주었다. 이것은 파이썬을 처음 배우는 사람들에게 매우 혼동스러운 부분이기도 하니 여러번 연습을 해 보는 것이 좋다.
다음처럼 하면 에러가 난다.
if <조건문>:
    <수행할 문장1>
<수행할 문장2>
    <수행할 문장3>
<수행할 문장2>가 들여쓰기가 되지 않았다.
또는
if <조건문>:
    <수행할 문장1>
    <수행할 문장2>
      <수행할 문장3>
<수행할 문장3>이 들여쓰기는 되었지만 <수행할 문장1>이나 <수행할 문장2>와의 들여쓰기의 깊이가 틀리다. 즉 들여쓰기는 언제나 같은 깊이로 해 주어야 한다.
그렇다면 들여쓰기는 공백으로 하는 것이 좋을까? 아니면 탭으로 하는 것이 좋을까? 이것에 대한 논란은 파이썬을 사용하는 사람들 사이에서 아직도 계속되고 있는 것인데 탭으로 하자는 쪽, 공백으로 하자는 쪽 모두다 일치하는 내용은 단 하나, 둘을 혼용해서 쓰지 말자는 것이다. 공백으로 할 거면 항상 공백으로 하고 탭으로 할 거면 항상 탭으로 하자는 말이다. 탭이나 공백은 프로그램 소스에서 눈으로 보이는 것이 아니기 때문에 혼용해서 쓰면 에러의 원인이 되기도 한다. 주의 하도록 하자.
[참고] ':'을 잊지 말자
if(조건문) 다음에는 반드시 ':'이 오게 된다. 이것은 특별한 의미라기보다는 파이썬의 문법 구조이다. 왜 하필이면 ':'인가에 대해서 궁금하다면 파이썬을 만든 Guido에게 직접 물어보아야 할 것이다. while이나 for, def, class 에도 역시 그 문장의 끝에 ':'이 항상 들어간다. 이 ':'을 가끔 빠뜨리는 경우가 많은데 주의하도록 하자.
파이썬이 다른 언어보다 보기가 쉽고 소스코드가 간결한 이유가 바로 ':'을 사용하여 들여쓰기(indentation)를 하게끔 만들기 때문이다. 하지만 숙련된 프로그래머들이 파이썬을 접할 때 가장 혼란스러운 부분이기도 하다.
if 문을 다른 언어에서는 { } 이런 기호로 감싸지만 파이썬에서는 들여쓰기로 해결한다.

조건문이란 무엇인가?

if <조건문>에서 사용되는 조건문이란 참과 거짓을 판단하는 문장을 말한다. 자료형의 참과 거짓에 대해서는 이미 알아 보았지만 몇가지만 다시 알아보면 다음과 같은 것들이 있다.

자료형의 참과 거짓

자료형거짓
숫자30
문자열"abc"""
리스트[1,2,3][]
터플(1,2,3)()
딕셔너리{"a":"b"}{}
따라서 위의 예에서 보았던
>>> money = 1
>>> if money:
에서 조건문은 money가 되고 money는 1이기 때문에 참이 되어 if문 다음의 문장을 수행하게 되는 것이다.

비교연산자

하지만 조건판단을 하는 경우는 자료형보다는 비교 연산자(<, >, ==, !=, >=, <=)를 쓰는 경우가 훨씬 많다.
다음은 비교연산자를 잘 설명해 준다.
비교연산자설명
x < yx가 y보다 작다
x > yx가 y보다 크다
x == yx와 y가 같다
x != yx와 y가 같지 않다
x >= yx가 y보다 크거나 같다
x <= yx가 y보다 작거나 같다
예를 통해서 위의 연산자들에 대해서 알아보자.
>>> x = 3
>>> y = 2
>>> x > y
True
>>>
x에 3을 y에 2를 대입한 다음에 x > y라는 조건문을 수행하니까 True를 리턴한다. 그 이유는 x > y라는 조건문이 참이기 때문이다.
>>> x < y
False
위의 조건문은 거짓이기 때문에 False를 리턴한다.
>>> x == y
False
x와 y는 같지 않다. 따라서 위의 조건문은 거짓이다.
>>> x != y
True
x와 y는 같지 않다. 따라서 위의 조건문은 참이다.
앞의 경우를 다음처럼 바꾸어 보자.
"만약 3000원 이상의 돈을 가지고 있으면 택시를 타고 그렇지 않으면 걸어가라"
위의 상황을 다음처럼 프로그래밍 할 수 있을 것이다.
>>> money = 2000
>>> if money >= 3000:
...     print("택시를 타고 가라")
... else:
...     print("걸어가라")
...
걸어가라
>>>
money >= 3000 이란 조건문이 거짓이 되기 때문에 else문 다음의 문장을 수행하게 된다.

and, or, not

또다른 조건 판단에 쓰이는 것으로 and, or, not이란 것이 있다.
각각의 연산자는 다음처럼 동작을 한다.
연산자설명
x or yx와 y 둘중에 하나만 참이면 참이다
x and yx와 y 모두 참이어야 참이다
not xx가 거짓이면 참이다
다음의 예를 통해 위의 사항을 반영해 보도록 하자.
"돈이 3000원 이상 있거나 풀러줄 시계가 있다면 택시를 타고 그렇지 않으면 걸어가라"
>>> money = 2000
>>> watch = 1
>>> if money >= 3000 or watch:
...     print("택시를 타고 가라")
... else:
...     print("걸어가라")
...
택시를 타고 가라
>>>
money는 2000이지만 watch가 1이기 때문에 money >= 3000 or watch라는 조건문이 참이 되기 때문에 if문 다음의 문장이 수행된다.

x in s, x not in s

더 나아가서 파이썬에서는 조금 더 재미있는 조건문들을 제공한다. 바로 다음과 같은 것들이다.
innot in
x in 리스트x not in 리스트
x in 터플x not in 터플
x in 문자열x not in 문자열
'in' 이라는 영어단어가 '~안에'라는 뜻을 가졌음을 상기해 보면 다음의 예들이 쉽게 이해가 될 것이다.
>>> 1 in [1, 2, 3]
True
>>> 1 not in [1, 2, 3]
False
위의 첫 번째 예는 “[1, 2, 3]이라는 리스트 안에 1이 있는가?” 라는 조건문이다. 1은 [1, 2, 3]안에 있으므로 참이 되어 True를 리턴한다. 두 번째 예는 "[1, 2, 3]이라는 리스트 안에 1이 없는가?" 라는 조건문이다. 1은 [1, 2, 3]안에 있으므로 거짓이 되어 False를 리턴한다.
다음은 터플과 문자열의 적용예를 보여준다.
>>> 'a' in ('a', 'b', 'c')
True
>>> 'j' not in 'python'
True
위의 것들을 이용하여 우리가 계속 사용해온 택시예제에 적용시켜 보자.
"만약 주머니에 돈이 있으면 택시를 타고, 없으면 걸어가라"
>>> pocket = ['paper', 'handphone', 'money']
>>> if 'money' in pocket:
...     print("택시를 타고 가라")
... else:
...     print("걸어가라")
...
택시를 타고 가라
>>>
['paper', 'handphone', 'money']라는 리스트에 안에 'money'가 있으므로 'money' in pocket은 참이 되어서 if문 다음의 문장이 수행되었다.

elif (다중 조건 판단)

if와 else만을 가지고서는 다양한 조건 판단을 하기가 어렵다. 다음과 같은 예만 하더라도 if와 else만으로는 조건 판단에 어려움을 겪게 된다.
"지갑에 돈이 있으면 택시를 타고, 지갑엔 돈이 없지만 시계가 있으면 택시를 타고, 돈도 없고 시계도 없으면 걸어가라“
위의 문장을 보면 조건을 판단하는 부분이 두 군데가 있다. 먼저 지갑에 돈이 있는지를 판단해야 하고 지갑에 돈이 없으면 다시 시계가 있는지를 판단한다.
if와 else만으로 위의 문장을 표현 하려면 다음과 같이 할 수 있을 것이다.
>>> pocket = ['paper', 'handphone']
>>> watch = 1
>>> if 'money' in pocket:
...     print("택시를 타고가라")
... else:
...     if watch:
...         print("택시를 타고가라")
...     else:
...         print("걸어가라")
...
택시를 타고가라
>>>
언뜻 보기에도 이해하기가 쉽지 않고 산만한 느낌이 든다. 위와 같은 점을 보완하기 위해서 파이썬에서는 다중 조건 판단을 가능하게 하는 elif라는 것을 사용한다.
위의 예를 elif를 이용하면 다음과 같이 할 수 있다.
>>> pocket = ['paper', 'handphone']
>>> watch = 1
>>> if 'money' in pocket:
...      print("택시를 타고가라")
... elif watch: 
...      print("택시를 타고가라")
... else:
...      print("걸어가라")
...
택시를 타고가라
즉, elif는 이전 <조건문>이 거짓일 때 수행되게 된다. if, elif, else의 기본 구조는 다음과 같다.
If <조건문>:
    <수행할 문장1> 
    <수행할 문장2>
    ...
elif <조건문>:
    <수행할 문장1>
    <수행할 문장2>
    ...
elif <조건문>:
    <수행할 문장1>
    <수행할 문장2>
    ...
...
else:
   <수행할 문장1>
   <수행할 문장2>
   ...
위에서 보듯이 elif는 개수에 제한 없이 사용할 수 있다. (참고: 이것은 마치 C언어의 switch문과 비슷한 것이다.)

pass의 사용

가끔 조건문을 판단하고 참 거짓에 따라 행동을 정의 할 때 아무런 일도 하지 않게끔 설정을 하고 싶을 때가 생기게 된다. 다음의 예를 보자.
"지갑에 돈이 있으면 가만히 있고 지갑에 돈이 없으면 시계를 끌러라“
위의 예를 pass를 적용해서 구현해 보자.
>>> pocket = ['paper', 'money', 'handphone']
>>> if 'money' in pocket:
...     pass 
... else:
...     print("시계를 끌른다")
...
pocket이라는 리스트 안에 'money'란 문자열이 있기 때문에 if문 다음문장인 pass가 수행되었고 아무런 결과값도 보여주지 않는 것을 확인 할 수 있다.

한줄 짜리 if문

위의 예를 보면 if문 다음의 수행할 문장이 한줄이고 else문 다음에 수행할 문장도 한줄이다. 이렇게 수행할 문장이 한줄일때 조금 더 간편한 방법이 있다. 위에서 알아본 pass를 사용한 예는 다음처럼 간략화 할 수 있다.
>>> pocket = ['paper', 'money', 'handphone']
>>> if 'money' in pocket: pass
... else: print("시계를 끌른다")
...
if문 다음의 수행할 문장을 ':'뒤에 바로 적어 주었다. else문 역시 마찬가지이다. 이렇게 하는 이유는 때때로 이렇게 하는 것이 보기에 편하게 때문이다.
출처 : 점프 투 파이썬

댓글 없음:

댓글 쓰기