You are currently viewing Compare strings using either ‘==’ or ‘is’ sometimes produces a different result.

Comparing strings using either ‘==’ or ‘is’ sometimes produces a different result. In Python programming, string comparison is a fundamental operation. Normally the ‘==’ operator is used to check if two strings have the same content. However the ‘is’ operator not only checks the content but also the identity of objects.

Advertisements

Though the ‘is’ operator determines whether two strings are equal, it can sometimes lead to unexpected outcomes. In this article, we will discuss string comparison in Python and see why these seemingly interchangeable operators, ‘==’ and ‘is,’ can occasionally yield different results.

1. Quick Example: Unexpected Result of ‘==’ and ‘is’

One scenario where the use of the ‘is’ operator with strings can produce unexpected results is when dealing with string interning and string concatenation. While it might not always lead to “wrong” results, it can certainly lead to surprising behavior.

See the below example we will explain this later on in this article:


# Unexpected results example
a = 'hello'
b = 'world'
c = a + ' ' + b

# Using 'is' to compare c with a concatenated string
result1 = (c is 'hello world')
result2 = c == 'hello world'
print(result1)  

# Outputs: False
print(result2)  
# Outputs: True

2. How String is Stored in Python

In Python, strings are immutable sequences of characters, which means once you create a string, you cannot modify its content. Python uses a concept called “string interning” for some strings. String interning is a memory optimization technique where Python caches and reuses string objects to save memory.

Python automatically interns short, simple strings. These interned strings are stored in a special memory pool, and multiple references to the same string will share the same memory location.

To explore how strings are stored and when they are interned, we can use the id() function, which returns the memory address of an object.

Let’s see some code examples:


# Checking the Memory address of a String
a = 'abc'
b = 'abc'

print(id(a))  
# Memory address of 'a' = 140731691700000

print(id(b))  
# Memory address of 'b'= 140731691700000

In the below example, we explicitly use sys.intern() to intern ‘hello’, and both x and y will share the same memory address.


# Intering of a String
import sys

x = sys.intern('hello')
y = sys.intern('hello')

print(id(x))  
# Memory address of '1180199505776'

print(id(y))  
# Memory address of '1180199505776'

3. The ‘==’ Operator in Comparing Strings

The ‘==’ operator is commonly used to check if two strings have matching content. It is important to understand how it works, especially in cases where the results may appear unexpected.

The ‘==’ operator does not compare the memory addresses of variables. If the content of two strings is identical, the ‘==’ operator will return True, indicating that the strings are equivalent.


# Using '==' for comparing strings
text1 = 'hello'
text2 = 'hello'

# Using '==' for comparison
result = text1 == text2  
print(result)  

# Output: True

In this example, ‘text1’ and ‘text2’ share the same content, so the ‘==’ operator returns True.


# Using == for comparing differnt string
text1 = 'hello'
text2 = 'world'

# Using '==' for comparison
result = text1 == text2 
print(result)  

# Output: False

4. The ‘is’ Operator in String Comparision

Just like the ‘==’ Operator python also has the ‘is’ operator. Unlike the ‘==’ operator, which checks for the equality of string content, the ‘is’ operator examines the identity of objects in memory. This distinction can lead to varying results when comparing strings, making it crucial to understand when and how to use the ‘is’ operator.

The ‘is’ operator evaluates whether two variables reference the same object in memory. When used with strings, it checks if both variables point to the same string object in memory. If they do, the ‘is’ operator returns True; otherwise, it returns False.

See the below code example, we have used the ‘is’ operator to compare if the two variables are pointing to the same memory location or not.


# Using 'is' opertor for string comparision
text1 = 'hello'
text2 = 'hello'
result = text1 is text2  # Using 'is' for comparison
print(result)  

# Output: True

Now see the below example, when assigning ‘text1’ to ‘text2,’ both variables point to the same string object, resulting in a True outcome.


# Using 'is' for comparison
text1 = 'python'
text2 = text1
result = text1 is text2  
print(result)  

# Output: True

5. Why Do ‘is’ and ‘==’ Sometimes Produce Different Results?

The behavior of the ‘==’ and ‘is’ operators generally work predictably, there are scenarios where their behavior diverges, resulting in seemingly unexpected results. There are certain reasons and one of them is the Python way of storing the string data in the memory.

To illustrate the behaviour of these two operators for comparing the string, let’s consider an example:


# Using both '==' and 'is' for comparision
a = 'hello'
b = 'world'
c = a + ' ' + b

# Using 'is' to compare c with a concatenated string
result = (c is 'hello world')
print(result)  

# Outputs: False

In the above example, we have three string objects: a, b, and c. When we concatenate a and b with a space in between, we create a new string object c. Surprisingly, using the ‘is’ operator to compare c with the concatenated string 'hello world' returns False.

This unexpected behavior occurs because the string 'hello world' is not interned, while c is a new string created through concatenation. Python doesn’t intern the result of string concatenation in the same way it interns string literals.

5.1 String interning

Python interns (reuses) small string literals to optimize memory usage, so identical string literals reference the same memory location. This is why the ‘is’ operator may return True for them.

Python maintains an internal cache for small immutable objects like strings. When you create a string literal (e.g., 'hello'), Python checks if it already exists in the cache. If it does, new references point to the same object. This behavior can lead to ‘is’ comparisons returning True for identical string literals because they share the same memory location.


# String Internnig Example
s1 = 'hello'
s2 = 'hello'
print(s1 is s2)  

# True, both s1 and s2 reference the same 'hello' object

5.2 Dynamic String Generation

String generation through dynamic operations like join() or string formatting creates new string objects, resulting in non-identical references. This is why the ‘is’ operator may return False.

Operations like join() or string formatting construct new strings by combining existing ones. These operations create fresh string objects, even if the resulting content is the same. As a result, ‘is’ comparisons return False because the references point to different memory locations.


# Using join() to generate dynamic String
s1 = 'hello'
s2 = ''.join(['h', 'e', 'l', 'l', 'o'])
print(s1 is s2)  

# False, s1 and s2 are distinct string objects

6. The Role of Object Identity in String Comparison

When comparing strings, two commonly used operators are == (equality) and is (identity). The == operator focuses on content equality, while the is operator emphasizes object identity. The is operator may return True in cases where Python reuses memory for identical string literals.

For dynamically-generated strings or separate string objects, even with matching content, the is operator often returns False. It explains why these operators can sometimes produce different results when comparing strings.

See the below example that explains how we have checked for the content of the string variable.


# Check the content of string variable
s1 = 'hello'
s2 = 'hello'
result = s1 == s2  

# True, as the content of s1 and s2 is the same

In the below code example, we have used the ‘is’ operator to see the object memory address and compare them. Both of the variables are pointing to the same memory place which is why the result is ‘True’.


# Check the ids of the string
s1 = 'hello'
s2 = 'hello'
result = s1 is s2  

# True, because s1 and s2 reference the same 'hello' object

7. ‘==’ vs ‘is’ operator when to use which

See the following table to understand when to use which operator for the string comparison. This table will give you the ultimate guide to using the ‘==’ and ‘is’ operators in Python.

Comparison TypeUse == (Equality)Use is (Identity)
Content EqualityWhen comparing actual content for equality.When checking if two strings are the same object.
Immutable ObjectsFor comparing immutable objects based on content.When explicitly confirming object identity.
Testing for NoneAlways use is for checking if a variable is None.To verify if an object is None, ensuring accuracy.
Common String ComparisonsIn everyday programming scenarios with strings.For verifying if two variables reference the same object.
Complex Object ComparisonWhen comparing complex objects for content.When dealing with objects with custom is behavior.
Comparison Table

8. Summary and Conclusion

In this article. we have explained the == and is operators in Python, with examples where they can produce different results. If you have any questions, please don’t hesitate to ask in the comment section below.

Happy Coding!

Related Article