• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Justin Joyce

Practical tips and tutorials about software development.

  • Standing Invitation
  • Featured Posts
  • Latest
  • About

Python “is” operator vs double equals “==”

Posted Feb 11, 2023 — Updated Jan 10, 2024

Python’s is operator compares object identity, while == compares object values.

Python “is” operator

In Python, is compares identity. In other words, it checks if two objects are the same object. It does not care if they have equal values, it cares if they have the same id in memory. This is why you often see is None comparisons in Python; there is only one None. On my machine, this is its id:

id of None

Here are some examples of how is behaves:

1 is 1 # True, this is a primitive value
"a" is "a" # True, this is a primitive value

my_obj = {}
my_obj is my_obj # True, this is the same object

{} is {} # False, these are two different dicts
[] is [] # False, these are two different lists

a = 500
b = 500
a is b # False. Yep, False.

You might see the last example above and think: “What? 500 is not 500?” Nope, not if you’re using is. At startup, Python caches—Python calls it “interning”—a set of commonly-used integers. Specifically, it pre-builds -5 to 256. Any integers outside of that range are constructed as they’re needed, and each construction will have a different location in memory. The same thing holds true for strings:

one = "justin"
two = "justin"

one is two # True. This seems ok..

three = "just in"
four = "just in"

three is four # False. Wait what?

The full explanation for why strings behave this way is a bit long for this post, but if you’re curious here’s a thorough stack overflow explanation. Tldr: When comparing strings or numbers, you should use ==.

Python double equals == operator

Unless you’re comparing to None, True, or False, == should be your default. Python’s == will compare the values being tested, not their identities. Let’s use the same examples as above:

1 == 1 # True
"a" == "a" # True

my_obj = {}
my_obj == my_obj # True

{} == {} # True
[] == [] # True

a = 500
b = 500
a == b # True

That’s better.

Under the hood, == uses an object’s __eq__ method, which typically looks something like this:

my_dict = {}
help(my_dict.__eq__)

"""
...
__eq__(self, value, /)
    Return self==value.
...
"""

Instead of comparing memory locations—which is almost certainly not what you’re after—__eq__ compares the actual values.

__eq__ is one of many double-underscore or “dunder” methods in Python. There are tons of dunder methods built into common Python objects, this post has lots of details.

Conclusion

Unless you know for certain it’s safe to use is, you should use ==. If you’re comparing strings or numbers, you should always use ==.


Helpful Links

  • Official Python docs for is
  • Official Python docs for __eq__
  • Stackoverflow thread about integer interning
  • Stackoverflow thread about string interning
  • Good blog post walking through Python dunder methods

Filed Under: Python

Primary Sidebar

Recent Posts

  • Every Built-In Vim Color Scheme (with screenshots)
  • Reverse a string in Python
  • Meeting Cost Calculator
  • Vim find and replace
  • What makes an effective development team

Categories

  • Arrays (5)
  • Command Line (9)
  • Dates (3)
  • Featured (7)
  • Git (7)
  • Golang (5)
  • Javascript (8)
  • Productivity (8)
  • Projects (4)
  • Python (15)
  • Regex (2)
  • Ruby (3)
  • Shell (2)
  • Thoughts (2)
  • Tips (11)
  • Tools (3)
  • Tutorials (1)
  • Vim (4)

Archives

  • July 2024 (1)
  • February 2024 (1)
  • January 2024 (1)
  • December 2023 (1)
  • November 2023 (1)
  • October 2023 (4)
  • September 2023 (1)
  • August 2023 (2)
  • July 2023 (5)
  • June 2023 (3)
  • May 2023 (6)
  • April 2023 (5)
  • March 2023 (5)
  • February 2023 (10)
  • January 2023 (6)
  • December 2022 (7)

Copyright © 2025 · Contact me at justin [at] {this domain}

  • Privacy Policy