Python’s identity operator is is: it checks whether two references point to the very same object, while == checks whether their values are equal. Use is mainly for comparisons with None and other deliberate identity checks; for ordinary value comparisons, use ==.
What Identity Means in Python
Python programs work with objects. An object has a value, a type, and an identity: a way to distinguish that particular object from other objects, even if they have equal values. A variable name refers to an object; it is not a box that permanently contains a value.
The expression a is b evaluates to True when a and b refer to the same object. Otherwise, it evaluates to False. The equality expression a == b asks whether the objects are equal according to their equality behavior, which is commonly based on their contents.
For example, two separately created lists can have the same contents but remain distinct objects:
a = [1, 2]
b = [1, 2]
print(a == b) # True: their contents compare equal
print(a is b) # False: they are separate list objects
Assigning one name to another creates a second reference to the same object:
a = [1, 2]
b = a
print(a == b) # True
print(a is b) # True
How is and is not Work
is and its opposite, is not, are comparison operators. Each returns a Boolean result, True or False. They do not call an object’s value-equality method to decide whether the objects are equivalent; they test whether the references identify the same object.
A common way to inspect identity while learning is Python’s built-in id() function. During an object’s lifetime, its identity remains constant. In CPython, id() is commonly related to a memory address, but Python does not require that implementation. Treat the returned number as an identity token, not as a portable address or a value to compare across program runs.
a = []
b = a
print(id(a) == id(b)) # True
print(a is b) # True
In real code, use is directly when identity is what you mean. Comparing id(a) == id(b) is less clear and can be misleading if objects are no longer alive and an implementation reuses an identity value.
When to Use the Identity Operator
The standard, most important use is testing whether a value is None:
result = find_item()
if result is None:
print("No item was found")
Use is not None for the opposite test. This is preferred to result == None because None is a unique singleton, and the test expresses identity directly. It also avoids surprising equality behavior from custom objects.
Identity checks can also be appropriate when an API specifically gives you a shared sentinel object, or when you need to know whether two references point to one mutable object. For instance, a function might use a unique sentinel to tell the difference between an omitted argument and an argument explicitly set to None:
_MISSING = object()
def read_value(value=_MISSING):
if value is _MISSING:
return "argument omitted"
return value
Here, the sentinel is deliberately created once and reused. The identity test reliably detects that exact marker object.
Why is Is Not a Replacement for ==
For numbers, strings, tuples, and other ordinary values, equality is usually the comparison you want. Two objects may have equal values even though they are distinct objects:
first = "hello"
second = "".join(["he", "llo"])
print(first == second) # True
Whether first is second is true is not a reliable way to test whether the strings contain the same text. Python implementations may reuse or intern some immutable objects as an optimization, and the circumstances can vary. The same caution applies to small integers and other objects: an identity result that happens to be true in one environment is not a substitute for value equality.
For mutable objects, the distinction is especially useful. If two names refer to the same list, changing the list through either name is visible through the other. If two lists merely compare equal, changing one does not change the other. Use is to ask whether they are the same shared object; use == to ask whether their current values compare equal.
Common Mistakes and Comparisons
- Using
isfor a number or string: writecount == 0orname == "Ada", not an identity comparison. - Assuming equal means identical: two independently created lists can satisfy
a == bwhilea is bis false. - Assuming different names mean different objects: assignment such as
b = amakes both names refer to the same object. - Confusing identity with type:
type(a) is type(b)asks whether both values have the same type object; it does not test whether the values are equal. - Using equality to check for
None: prefervalue is Noneorvalue is not None.
Python classes can define equality behavior, so == may compare selected attributes or other logical content rather than every detail of an object. The meaning of equality depends on the type. Identity, by contrast, continues to mean that both references lead to the same object.
Frequently Asked Questions
What does is mean in Python?is checks whether two expressions refer to the same object. It returns True for identical object references and False otherwise.
What is the difference between is and ==?is tests object identity; == tests value equality as defined by the objects’ type. Two different objects can be equal without being identical.
Should I use is or == for None?
Use value is None to check for None, and value is not None to check that a value is present.
Can I use is to compare strings or integers?
Usually, no. Use == to compare their values. Object reuse can make identity results appear to work accidentally, but that behavior is not a dependable value comparison.
How can I tell whether two variables refer to the same list?
Use a is b. If it is true, both names refer to the same list object; if it is false, they refer to different objects, even if a == b is true.
A Practical Rule to Remember
Ask what question the code needs to answer. If it is “Do these values compare as equal?”, use ==. If it is “Are these references to this exact object?”, use is. For the routine special-value check, write is None or is not None. This distinction keeps comparisons clear and avoids depending on implementation-specific object reuse.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Wireless Controller Charging: Can You Play While Plugged In?
- Secure a Node.js API: Layered Checklist
- Zoom Desktop Client: Features, Setup, and Fixes
- Python Integer Identity: Why It Varies by Run
- Can Technology Solve Poverty? Facts & Limits
- Cannot Detect Device? Fixes for USB & Bluetooth