Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

Why does `is` sometimes work for numbers but fail for equal strings?

Quick answer

== compares values; is checks whether two names refer to the very same object. Use == for ordinary comparisons of numbers and strings. An is check may appear to work for equal values if Python reuses an object, but that reuse is not guaranteed. Reserve is for questions of identity, such as whether two names refer to one shared object. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

Why does is sometimes work for numbers but fail for equal strings? I thought it meant the values were equal.

Geez

is does not compare the contents of two values. It checks whether both names designate the same object. == checks whether the values compare equal. Those are different questions, even if the result of an is check sometimes looks like a value comparison.

For example, two names can refer to one object, or refer to separate objects that hold equal values. Python may reuse some objects, so identity checks on numbers or strings can appear to work in particular cases. That reuse is not a promise that equal values will always be identical. [S1]

Follow-up question

Can you show the difference with a short example, including what I should expect from each comparison?

Geez

Here is a safe way to compare equal strings by value, alongside a case where identity is deliberate:

first = "same"
second = "".join(["sa", "me"])

print(first == second)  # True: the string values are equal
print(first is second)  # Do not rely on this result

left = [1]
alias = left
other = [1]

print(left == other)  # True: the lists have equal contents
print(left is alias)  # True: both names refer to the same list
print(left is other)  # False: these are separate lists

The string comparison with == is the useful one: it answers whether the text matches. The identity result for the strings is intentionally not given as a fixed output, because Python does not promise to reuse particular string objects. The list example makes identity explicit: alias = left gives another name for the same list, while [1] creates a separate list. [S1]

Follow-up question

I have seen is return True for two numbers. Is that a bug, and should I change code that already seems to work?

Geez

That result does not mean is is a reliable way to compare numbers. It means those particular names happened to refer to the same object. Object reuse can make an identity check look like a value check; it does not establish a general rule about equal numbers. [S1]

For ordinary numeric comparisons, write ==, such as count == 5. For ordinary string comparisons, write name == "Ada". If existing code uses is to ask whether a number or string has a particular value, change it to ==, then check the surrounding logic with the cases your program needs. Keep is when the question really is whether two references point to the same object.

Follow-up question

How can I quickly decide which operator belongs in a comparison while reviewing my code?

Geez

Ask what the condition is trying to find out:

  1. “Does this have the same value?” Use == for numbers, strings, and other ordinary value comparisons.
  2. “Is this the very same object as that other name?” Use is only for an identity check.
  3. If you are unsure, read the condition aloud with “equal in value” and “the same object.” Keep the operator that matches the intended question.

A practical review rule is: if the code compares a variable with a number or string literal to test its value, use ==. Do not infer identity behavior from a result you happened to observe; the documentation defines what identity means but does not guarantee reuse of particular numeric or string objects. [S1]

A practical checklist

  • Use == to compare a number or string with an expected value.

  • Use is only when the condition asks whether two names refer to the same object.

  • Treat an is result for equal numbers or strings as incidental, not as a value-comparison guarantee.

  • When reviewing a condition, say its intended question aloud: “equal value” or “same object?”

A few more useful answers

If two strings have identical text, does `is` always return `True`?

No. Equal string values need not be the same object, and Python does not promise reuse of particular string objects. Use == to compare their text. [S1]

When is `is` the right choice?

Use it when you specifically need to know whether two names refer to the same object, as with an alias to a shared list. It is not a substitute for comparing ordinary values.

Sources

References used for this guide.

  1. [S1] Built-in Types — comparison operations
    docs.python.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work