This is one of the most commonly misused Python features and it fails silently, which makes it especially dangerous in production code. a = "hello" b = "hello" print(a == b) print(a is b) Enter fullscreen mode Exit fullscreen mode Both print True. Safe, right? Now try this: a = "hello world" b = "hello world" print(a == b) print(a is b) Enter fullscreen mode Exit fullscreen mode a == b prints True. a is b might print False. Same code structure. Different result. Here is exactly why. What is and == Actually Check == checks value equality. Do these two objects represent the same value? is checks identity equality. Are these two names pointing to the exact same object in memory? Two objects can be equal in value while being completely different objects in memory. String Interning Python automatically interns some strings. Interning means Python reuses a single object for multiple names with the same value, rather than creating separate objects. Short strings that look like valid Python identifiers are automatically interned. Longer strings or strings with spaces are not always interned. a = "hello" b = "hello" print(a is b) # True -- both point to the same interned object a = "hello world" b = "hello world" print(a is b) # False -- two separate objects (implementation dependent) Enter fullscreen mode Exit fullscreen mode The behavior for longer strings is implementation dependent and version dependent. You cannot rely on it. Integer Caching Python caches integers from -5 to 256. Integers in this range are always the same object regardless of how many names point to them. a = 100 b = 100 print(a is b) # True -- cached integer, same object a = 1000 b = 1000 print(a is b) # False -- outside cache range, separate objects Enter fullscreen mode Exit fullscreen mode a = 256 b = 256 print(a is b) # True -- last cached integer a = 257 b = 257 print(a is b) # False -- first uncached integer Enter fullscreen mode Exit fullscreen mode The Interview Trap x = None y = None print(x is y) # True -- None is a singleton print(x == y) # True x = [] y = [] print(x is y) # False -- two separate empty list objects print(x == y) # True -- both represent empty lists Enter fullscreen mode Exit fullscreen mode The canonical use case for is is checking against None, True, and False. These are singletons in Python. Every None in your program is the same object. # Correct pattern if value is None: handle_missing() # Incorrect pattern (works by accident, not by design) if value == None: handle_missing() Enter fullscreen mode Exit fullscreen mode The == version works because NoneType.__eq__ is implemented but using is is the semantically correct choice and is what PEP 8 requires. The Practical Rule Use == for value comparison in all application code. Use is only for checking against None, True, and False. Never use is to compare strings or integers in application code, even if it works in testing. Practice identity vs equality problems at PyCodeIt.
Why Python's `is` Keyword Will Betray You If You Trust It for Equality
Full Article
Original Source
Read the full article at Dev →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.