Identity and Equality¶
Understanding the difference between is (identity) and == (equality) operators.
Identity (is)¶
The is operator checks if two names refer to the same object in memory:
a = [1, 2, 3]
b = a
print(a is b) # True (same object)
print(id(a) == id(b)) # True (same id)
Different Objects¶
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # False (different objects)
print(id(a)) # 140234567890
print(id(b)) # 140234567999
Even though a and b have the same values, they are different objects in memory.
Equality (==)¶
The == operator checks if two objects have the same value:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (same values)
print(a is b) # False (different objects)
When to Use Each¶
Use is for Singletons¶
# For None
if x is None:
print("x is None")
if x is not None:
print("x has a value")
# For True/False (rare, but valid)
if flag is True:
pass
if flag is False:
pass
Use == for Values¶
# For comparing values
if x == 42:
pass
if name == "Alice":
pass
if items == [1, 2, 3]:
pass
Common Pitfall: Integer Caching¶
Python caches small integers (-5 to 256), which can cause confusion:
# Small integers are cached
a = 256
b = 256
print(a is b) # True (cached)
# Large integers are not
a = 257
b = 257
print(a is b) # False (different objects)
print(a == b) # True (same value)
Rule: Always use == for comparing values, even integers.
String Interning¶
Similar caching happens with some strings:
a = "hello"
b = "hello"
print(a is b) # True (interned)
a = "hello world!"
b = "hello world!"
print(a is b) # May be False
print(a == b) # True (same value)
Special Cases¶
Augmented Assignment¶
Augmented assignment behaves differently based on mutability:
# Mutable: modifies in place
x = [1, 2]
y = x
x += [3, 4]
print(x is y) # True (same object)
# Immutable: creates new object
x = 10
y = x
x += 5
print(x is y) # False (different objects)
None Comparison¶
Always use is for None:
# Correct
if result is None:
pass
# Incorrect (works but not recommended)
if result == None:
pass
Boolean Context¶
For boolean checks, often no comparison needed:
# Instead of
if flag == True:
pass
# Prefer
if flag:
pass
# Instead of
if len(items) == 0:
pass
# Prefer
if not items:
pass
Summary Table¶
| Operator | Checks | Use For | Example |
|---|---|---|---|
is |
Identity (same object) | None, singletons |
x is None |
== |
Equality (same value) | Values, objects | x == 42 |
is not |
Not same object | None check |
x is not None |
!= |
Not same value | Value comparison | x != 0 |
Key Takeaways¶
ischecks if two names point to the same object==checks if two objects have the same value- Use
isforNone,True,False - Use
==for all value comparisons - Don't rely on integer/string caching
- Identity implies equality, but not vice versa