BioPlayground

🧬
목록으로

Truthy/Falsy와 is vs ==

Python에서 어떤 값이 True/False로 평가되는지, is와 ==의 차이는 무엇인지 명확하게 설명합니다.

입문
|
8
|
검증 완료 (2026-07)
truthyfalsyis==None 비교Python 비교
진행률0/18 (0%)

Truthy/Falsy와 is vs ==

이 토픽을 마치면

Python에서 어떤 값이 조건문에서 True/False로 평가되는지 알 수 있고, is==를 올바르게 구분해서 사용할 수 있습니다.


Truthy와 Falsy

Python의 if문은 True/False만 받는 것이 아닙니다. 어떤 값이든 조건으로 사용할 수 있습니다:

python
if "hello":
print("실행됨") # 실행됨!
if 0:
print("실행 안 됨") # 실행 안 됨

Python은 모든 값을 Truthy(참으로 취급)와 Falsy(거짓으로 취급)로 나눕니다.


Falsy 값 — 외우면 끝

Falsy인 값은 정해져 있습니다. 나머지는 전부 Truthy입니다:

python
# 이것들이 Falsy (False로 평가)
False
None
0 # 정수 0
0.0 # 실수 0
"" # 빈 문자열
[] # 빈 리스트
{} # 빈 딕셔너리
set() # 빈 세트
python
# 확인해보기
values = [False, None, 0, 0.0, "", [], {}, set()]
for v in values:
print(f"{str(v):10} → {bool(v)}")
# False → False
# None → False
# 0 → False
# 0.0 → False
# → False
# [] → False
# {} → False
# set() → False

핵심 규칙: "비어있거나 0이면 Falsy". 이것만 기억하면 됩니다.


실무 패턴 — 빈 값 체크

Truthy/Falsy를 활용하면 코드가 간결해집니다:

python
# 리스트가 비어있는지 확인
items = []
# 이렇게 쓸 필요 없음
if len(items) > 0:
print("있음")
# 이렇게 쓰면 됨
if items:
print("있음")
python
# 문자열이 비어있는지 확인
name = ""
if name:
print(f"안녕, {name}")
else:
print("이름을 입력해주세요")
python
# None 체크와 기본값
def greet(name=None):
name = name or "손님"
return f"안녕하세요, {name}"
print(greet()) # "안녕하세요, 손님"
print(greet("철수")) # "안녕하세요, 철수"

or 연산자는 왼쪽이 Falsy면 오른쪽을 반환합니다. 기본값 패턴으로 자주 씁니다.


== — 값이 같은가

==는 두 값이 동등한지 비교합니다:

python
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True — 내용이 같으니까

두 리스트는 별개의 객체이지만, 담고 있는 값이 같으므로 ==True입니다.

python
print(1 == 1.0) # True — 숫자 값이 같으면
print("abc" == "abc") # True
print([1] == [1]) # True

is — 같은 객체인가

is는 두 변수가 메모리에서 같은 객체를 가리키는지 비교합니다:

python
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — 값이 같음
print(a is b) # False — 다른 객체
print(a is c) # True — 같은 객체를 가리킴

ab는 내용은 같지만 서로 다른 리스트 객체입니다. c = a는 같은 리스트를 가리키므로 isTrue입니다.

python
# id()로 확인 가능
print(id(a)) # 140234567890
print(id(b)) # 140234567920 (다른 주소)
print(id(c)) # 140234567890 (a와 같은 주소)

None 비교 — is를 써야 하는 이유

python
result = None
# ✅ 올바른 방법
if result is None:
print("결과 없음")
# ❌ 권장하지 않는 방법
if result == None:
print("결과 없음")

None은 Python 전체에서 단 하나의 객체입니다. is로 비교하면 "이것이 바로 그 None 객체인가?"를 직접 확인합니다.

==는 클래스가 __eq__ 메서드를 오버라이드하면 예상과 다르게 동작할 수 있습니다:

python
class Tricky:
def __eq__(self, other):
return True # 무엇과 비교해도 True
t = Tricky()
print(t == None) # True — 위험!
print(t is None) # False — 안전

PEP 8(Python 공식 스타일 가이드)에서도 None 비교는 is를 사용하라고 명시합니다.


정수 캐싱 트랩

python
a = 256
b = 256
print(a is b) # True — CPython이 -5~256을 미리 캐싱
a = 257
b = 257
print(a is b) # False — 범위 밖이라 별도 객체 생성

CPython은 작은 정수(-5~256)를 미리 만들어놓고 재사용합니다. 이 범위 안에서는 isTrue지만, 밖에서는 False입니다. 이것이 값 비교에 is를 쓰면 안 되는 이유입니다. is는 오직 None, True, False 비교에만 사용합니다.

python
# 문자열에서도 비슷한 현상
a = "hello"
b = "hello"
print(a is b) # True — 인터닝(interning) 발동
a = "hello world!"
b = "hello world!"
print(a is b) # False — 공백+특수문자 포함 시 인터닝 안 됨

함수 매개변수의 기본값과 None

python
# ❌ 위험한 패턴
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("a")) # ["a"]
print(add_item("b")) # ["a", "b"] — 이전 호출의 결과가 남아있음!
# ✅ 안전한 패턴
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items

가변 객체(리스트, 딕셔너리)를 기본값으로 쓰면 모든 호출이 같은 객체를 공유합니다. None을 기본값으로 쓰고 함수 안에서 새 객체를 만드는 것이 Python의 표준 패턴입니다.


bool()과 Truthy/Falsy 활용

python
# 빈 값 검증을 간결하게
data = {"name": "철수", "email": "", "phone": None}
# ❌ 길고 반복적
if data["name"] is not None and data["name"] != "":
print("name 있음")
# ✅ Truthy/Falsy 활용
if data["name"]:
print("name 있음")
# 유효한 값만 필터링
values = [0, "", None, "hello", [], [1, 2], False, 42]
valid = list(filter(None, values))
print(valid) # ["hello", [1, 2], 42]

filter(None, iterable)은 Falsy 값을 모두 제거합니다. 데이터 정제에서 자주 쓰이는 패턴입니다.


정리

비교의미사용 시점
==값이 같은가일반적인 값 비교
is같은 객체인가None, True, False 비교
!=값이 다른가일반적인 불일치 확인
is not다른 객체인가is not None
python
# 이 패턴들을 기억하세요
if x is None: # None 체크
if x is not None: # None이 아닌지 체크
if items: # 비어있지 않은지 (Truthy)
if not items: # 비어있는지 (Falsy)


any()와 all() — 컬렉션의 Truthy 활용

python
scores = [85, 92, 0, 78, 95]
print(any(scores)) # True — 하나라도 Truthy (0이 아닌 것 존재)
print(all(scores)) # False — 0이 Falsy
# 조건식과 함께
print(any(s >= 90 for s in scores)) # True — 90 이상이 있는가
print(all(s >= 60 for s in scores)) # False — 모두 60 이상인가

any()all()은 내부적으로 Truthy/Falsy 판별을 사용합니다. 조건을 간결하게 표현할 때 유용합니다.



단축 평가(Short-circuit) 활용

python
# or — 첫 Truthy를 반환 (없으면 마지막 값)
name = user_input or "기본이름"
# and — 첫 Falsy를 반환 (없으면 마지막 값)
result = data and data[0] # data가 비어있으면 [] 반환, 아니면 첫 원소

orand는 불리언을 반환하는 게 아니라, Truthy/Falsy 판단을 멈춘 시점의 값을 반환합니다. 기본값 설정이나 안전한 접근 패턴에 자주 쓰입니다.


==is의 차이를 모르면 찾기 어려운 버그가 생깁니다. 특히 None 비교에서 == 대신 is를 쓰는 습관은 Python 코드 품질의 기본입니다.