본문으로 건너뛰기
김신건의 로그

[Python] 연산자: 비교, 산술, 비트, 멤버십

· 수정 · 📖 약 1분 · 246자/단어 #python #operators #comparison #arithmetic #basics
python operators, python 연산자, is vs ==, operator precedence

분류

종류연산자예시
산술+ - * / // % ** @7 // 2, A @ B (행렬곱)
비교== != < <= > >=a == b
동일성is, is notx is None
멤버십in, not inkey in d
논리and or notx and y
비트& | ^ ~ << >>flags & MASK
할당= += -= *= /= //= %= **= &= |= ^= >>= <<=n += 1
조건식a if cond else b"pos" if x > 0 else "neg"
워러스:= (3.8+)if (n := len(xs)) > 10:
언패킹*, **f(*args, **kwargs)

산술 연산 디테일

나눗셈 / vs //

7 / 2       # 3.5  (float division, 항상 float)
7 // 2      # 3    (floor division)
7.0 // 2    # 3.0  (피연산자 타입 따름)

-7 / 2      # -3.5
-7 // 2     # -4   (floor, C와 다름)
-7 % 2      # 1    (Python: 부호는 divisor)

불변식: (a // b) * b + (a % b) == a. 항상 성립.

거듭제곱과 행렬곱

2 ** 10           # 1024
2 ** 0.5          # 1.4142135623730951
pow(2, 10, 1000)  # 24  (modular exponentiation)

# 행렬곱 (PEP 465, 3.5+)
import numpy as np
A @ B             # np.matmul(A, B)

비교 연산: 체이닝과 함정

Python 비교는 수학식처럼 체이닝된다.

python
x = 5
print(0 < x < 10)         # True (C: 0 < x then result < 10이라 망함)
print(1 == 1 == 1)        # True
print(1 < 2 > 1)          # True
print(1 < 2 < 1)          # False (단축 평가)
결과
True
True
True
False

체이닝은 and로 묶인 것과 동등. 0 < x < 10 == 0 < x and x < 10. 가운데 표현식은 한 번만 평가.

== vs is

==is
의미값(value) 동등동일(identity, 같은 객체)
호출__eq__()id 비교 (id(a) == id(b))
사용일반 비교None, True, False, singleton 비교
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)     # True (값)
print(a is b)     # False (다른 객체)

x = None
print(x is None)  # 권장
print(x == None)  # 비권장 (NumPy 같은 객체에선 위험)

작은 정수 캐싱(-5~256) 때문에 a is b가 우연히 True가 될 수 있다. 의존하지 말 것.

멤버십 연산

in은 컨테이너의 __contains__를 호출, 없으면 iteration으로 폴백.

1 in [1, 2, 3]            # True   - list: O(n)
"a" in {"a", "b"}         # True   - set: O(1)
"key" in {"key": 1}       # True   - dict: O(1) (키 검사)
"ell" in "hello"          # True   - str: 부분 문자열 검사

큰 list에 반복 멤버십 검사가 필요하면 set으로 변환.

논리 연산: short-circuit

a and b    # a가 falsy면 a, 아니면 b
a or b     # a가 truthy면 a, 아니면 b
not a      # bool 반환

# 활용
default = user_input or "anonymous"
log = logger and logger.info("msg")
result = check() and process()

bool을 반환하지 않고 피연산자 그대로 반환하는 점에 주의(다른 언어와 다름).

비트 연산

a = 0b1100   # 12
b = 0b1010   # 10

a & b   # 0b1000 = 8
a | b   # 0b1110 = 14
a ^ b   # 0b0110 = 6
~a      # -13 (=-(a+1))
a << 2  # 48
b >> 1  # 5

Python int는 임의 정밀도 2의 보수 모델로 비트 연산이 안전.

비트 트릭

# 짝/홀
n & 1                  # 1이면 홀수

# 비트 카운트 (3.10+)
n.bit_count()

# 비트 길이
(255).bit_length()     # 8

# 부호 반전 없이 최하위 1비트
n & -n                 # 가장 낮은 set 비트 추출

할당 연산자: 가변/불변

+=는 가변 객체에선 in-place 수정, 불변에선 새 객체 생성.

python
# 리스트: in-place
xs = [1, 2]
ys = xs
xs += [3]
print(ys)         # [1, 2, 3] (같은 객체)

# 문자열: 새 객체
s = "abc"
t = s
s += "d"
print(t)          # 'abc' (영향 없음)
결과
[1, 2, 3]
abc

함수 인자가 list일 때 xs += [...]xs = xs + [...]가 호출자에게 다르게 보인다.

워러스 연산자 := (3.8+)

표현식 자리에서 할당. while 입력 반복이나 컴프리헨션 내 재사용에 유용.

# Before
while True:
    line = input()
    if not line:
        break
    process(line)

# After
while line := input():
    process(line)

# 컴프리헨션
results = [y for x in data if (y := f(x)) is not None]

우선순위 요약 (높음 → 낮음)

(), [], {}        # 괄호, 리터럴
x[i], x(args)     # 인덱싱, 호출
**                # 거듭제곱 (우결합)
+x -x ~x          # 단항
* / // % @        # 곱셈류
+ -               # 덧셈류
<< >>             # 비트 시프트
&                 # AND
^                 # XOR
|                 # OR
in not in is is not < <= > >= != ==   # 비교/멤버십/동일성
not               # 논리 NOT
and               # 논리 AND
or                # 논리 OR
if ... else       # 조건식
lambda            # 람다
:=                # 워러스

명시적 괄호 사용을 권장한다. 우선순위 외워서 쓰는 것보다 명확함이 우선.

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기