저는 임시글 목록에 블로그에 작성하면 좋을 것 같은 소스들을 저장해 놓는데 두번째 글은 가장 일찍 적어놨던 글을 선택했습니다. 1/13에 조금 작성해놓은 건데 블로그를 주말마다 쓰려고 하다보니 아직까지 완성을 안해놨더라구요.
이번에는 함수가 아닌 연산자를 다루어 보려고 합니다. 그 중에서도 논리연산자의 케이스를 가져왔습니다.
왜냐면, 이걸 응용한 단축평가가 정말 신기하게 작용하기 때문입니다.
일단 오늘도 간단한 정의와 함께 시작해보겠습니다.
연산자는 값을 계산하거나 평가하기 위해 필요한 부호입니다.
연산자에는 아래와 같이 다양한 연산자들이 존재합니다.
참고! 비교연산자의 ==과 is는 조금 다른 역할을 합니다. ==는 객체의 값을 직접비교하지만 is는 객체가 갖고 있는 메모리 주소를 비교합니다. 예를 들어 1==1.0은 True이지만 1 is 1.0은 False를 반환합니다.(그 이유는 1은 integer형태, 1.0은 Float형태로 메모리내 다른 주소에 저장되어 있기 때문입니다.)
오늘 글에서 다루고 싶은 주제인 단축평가입니다.
단축 평가는 논리 연산에서 두번째 피연산자를 평가하지 않고 결과를 결정하는 동작입니다.
글로 적는 것보다는 예시를 들어 설명하는 게 더 쉽기 때문에 바로 보시죠
test ='abcde'
print(('a' and 'f') in test) # False
print(('f' and 'a') in test) # True
처음 이 내용을 접하시는 분들은 첫 줄을 당연하다고 생각하지만 둘째 줄에서 갸우뚱하실 수 있습니다.
먼저 이 내용을 알기전에 연산자의 우선 순위와 string, integer와 boolean의 관계를 먼저 알아야 합니다.
제일 간단한 것부터!
연산자의 우선 순위는 다음과 같습니다.
우선순위 | 연산자 | 내용 |
---|---|---|
높음 | () | 소괄호, grouping |
[] | 인덱싱, 슬라이싱 | |
** | 거듭제곱 | |
+,- | 단항 연산자 양수/음수 | |
*, /, //, % | 산술연산자 | |
+,- | 산술연산자 | |
<,<=,>,>=,==,!= | 비교연산자 | |
is, is not | 객체 비교 | |
in,not in | 멤버십 연산자 | |
not | 논리 부정 | |
and | 논리 AND | |
낮음 | or | 논리 OR |
따라서 예시에서는 소괄호안의 ('f' and 'a')와 ('a' and 'f')부터 평가가 되어야 합니다.
boolean값은 True/False라는 것을 모두 알고 있으실 겁니다. 또, True는 형변환시 값으로 1을 갖고 False는 0을 값으로 갖고 있습니다.
a= True
b= False
print(a+1) # 2
print(b+1) # 1
그런데 Python에서 string과 integer는 boolean으로 어떤 값을 갖고 있을까요?
a= 3.0
b= 3
c= 'apple'
d= 0
print(bool(a)) # True
print(bool(b)) # True
print(bool(c)) # True
print(bool(d)) # False
파이썬에서는 0이 아닌 값을 갖고 있으면 float, str, int상관없이 모두 True값으로 인식이 되고 0은 False로 인식하게 됩니다.
다시 예제로 돌아가보면, (f and a)와 (a and f)의 평가는 그럼 어떻게 진행될까요??
print('f' and 'a') # a
print('a' and 'f') # f
결과 값이 신기하게 and 뒤의 문자로 나오게 됩니다.
이것은 논리 연산자와 관계가 있어요
참고! 글을 작성하다가 궁금해서 하나 더 평가를 해봤습니다.
위의 b를 bool으로 형변환할 경우 True로 바뀌는데 그값을 다시 int로 형변환한다면??b=3 print(int(bool(b))) #1
결과는 쉽게 예상할 수 있었는데 순서대로 int->bool(3->True)로 변환 후 True->int(True->1)이 되는 걸 확인 할 수 있었습니다.
여기서는 논리연산자 중에서 and와 or만 다루겠습니다. 왜냐면 단축 평가와 연관된 게 두 연산자이기 때문!
print('f' and 'a') # a
print('a' and 'f') # f
논리 연산자는 Boolean으로 평가한 후에 값을 반환하는 연산자입니다.
무슨 말이냐면, 예시의 'f' and 'a'를 보면 Boolean 값으로 평가하기 위해 'f'와 'a'를 bool type으로 파이썬에서 자체적으로 암시적 형변환을 합니다.
'f','a' 둘 다 문자열이 존재하여 True값으로 반환되죠. 그럼 위의 식을 잠깐 동안 True and True로 바꾸게 되어 평가를 진행합니다.
and의 양쪽 모두 True이니깐 True가 반환되어야 하는데 평가를 위해 잠깐 암시적 형변환을 했기 때문에 출력되는 최종 값은 마지막에 평가한 대상의 형변환 전의 값으로 반환됩니다.
아마 다른 예시를 들면 이해가 쉬우실 것 같습니다.
숫자의 예시와 or로 한번 볼까요?
print(3 and 0) # 0
print(0 and 3) # 0
print(0 or 3) # 3
print(3 or 0) # 3
평가는 bool 타입으로 반환되는 값은 최종 평가 값이라고 말씀드렸던 것을 기억하세요!
1. 3 and 0은 3이 True이므로 0까지 확인 후 0이 False이므로 0을 그대로 반환합니다
2. 0 and 3은 단축 평가가 들어갑니다. 0은 False인데 and의 특성상 하나가 False면 전체가 False이므로 0에서 평가가 끝나고 0을 반환합니다.
3. 0 or 3은 0이 False이므로 or의 특성상 둘 다 확인할 필요가 있어 3을 보니 True네요. 그래서 마지막 평가한 True값인 3이 나오게 됩니다.
4. 3 or 0은 3이 True이므로 단축 평가가 들어가게 됩니다. or는 하나라도 True라면 True로 반환하는 특성이 있습니다. 그래서 마지막 평가값인 3이 반환이 됩니다.
숫자의 예시가 문자열의 예시보다 직관적이죠??
다들 이해가셨을 것이라 생각하고 마무리를 해봅시다.
다시 첫번째 예시로 돌아가 보면
test ='abcde'
print(('a' and 'f') in test) # False
print(('f' and 'a') in test) # True
첫 줄은 소괄호 안의 'a' and 'f'를 먼저 평가해보니 True and True이므로 마지막 True값인 'f'가 반환되었고 멤버십 연산자로 test의 문구 내에 들어 있는지 확인 했는데 없으므로 최종적으로 False가 반환됩니다.
둘째 줄은 같은 방식으로 소괄호 평가를 마치니 'a'가 반환되고 a는 test내에 존재하므로 True가 반환됩니다.
파이썬을 공부하면서 정말 신기한게 많은 것 같네요. 지금 2주정도 학습했는데 정말 배우기 쉬운 언어인것 같습니다.