C++이나 여느 언어 써보신 분은 a < b < c를 체크하려면 어떻게 해야되는지 잘 아실 겁니다. 바로 a<b && b<c로 써줘야 하는데요, a<b<c 이렇게 쓰면 operator associativity가 Left-to-right이므로 (a<b)<c, 따라서 bool값 < c 이렇게 됩니다. 컴파일 에러는 아니지만 의도하지 않은 결과가 나오게 되지요

그런데 파이썬에서는 그냥 a<b<c 이런식으로 쓰면 됩니다. 중간에 끼는 비교연산자는 아무거나 가능합니다. a<=b!=c>=d 뭐 이쁘진 않지만 이런식으로 쓰는 것도 가능합니다. 

(python docs)
6.10. Comparisons

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

파이썬에서 a<b<c는 a<b and b<c와 거의 동일한데, 비교연산자를 체이닝한 경우 y 부분은 딱 한번만 계산됩니다. a<b 부분이 False인 경우 z를 계산하지 않는 것은 동일합니다.

x = 0
def y():
    y.counter += 1
    return y.counter
y.counter = 0
z = 3

print(x < y() < z)    # y() is evaluated once
# print(x < y() and y() < z)  # y() is evaluated twice
print(y.counter)

예제를 만들어봤습니다. x < y() < z로 쓴 경우 y()는 딱 한번 실행되기 때문에 카운터를 찍어보면 1이지만 주석처리한 부분의 코드처럼 x<y() and y()<z로 쓰면 y()가 두번 호출돼 카운터값이 2가 됩니다.

Note that a op1 b op2 c doesn’t imply any kind of comparison between a and c, so that, e.g., x < y > z is perfectly legal (though perhaps not pretty).

이렇게 비교연산자를 연결했을 때 인접한 operand가 아니고 떨어져있는 operand끼리는 관계가 없습니다. 그러니 보기는 좀 그렇지만 x<y>z처럼 쓰는 것도 가능은 합니다

반응형