Skip to content

Python Not Equal: How to Use the != Operator

Updated on

The not equal operator in Python is !=. It compares two values and returns True if they are different, False if they are the same.

print(5 != 3)    # True
print(5 != 5)    # False
print("a" != "b")  # True

That is the short answer. The rest of this guide covers every detail you need: all comparison operators, how != behaves with different data types, the difference between != and is not, how to customize inequality for your own classes, and the common mistakes that trip up both beginners and experienced developers.

📚

Python Comparison Operators: Complete Reference

Before diving deeper into !=, here is the full set of comparison operators in Python. Each operator returns a boolean value (True or False).

OperatorNameExampleResultDescription
==Equal to5 == 5TrueTrue if both values are equal
!=Not equal to5 != 3TrueTrue if values are different
<Less than3 < 5TrueTrue if left is smaller
>Greater than5 > 3TrueTrue if left is larger
<=Less than or equal5 <= 5TrueTrue if left is smaller or equal
>=Greater than or equal5 >= 3TrueTrue if left is larger or equal
isIdentitya is bvariesTrue if same object in memory
is notNot identitya is not bvariesTrue if different objects in memory

The first six (==, !=, <, >, <=, >=) compare values. The last two (is, is not) compare object identity -- whether two variables point to the exact same object in memory. This distinction matters, and we will cover it in detail below.

Using != with Different Data Types

The != operator works across all Python data types. Here is how it behaves with each one.

Strings

String comparison is case-sensitive. "Hello" and "hello" are not equal.

print("apple" != "banana")   # True
print("apple" != "apple")    # False
print("Apple" != "apple")    # True  (case-sensitive)
print("" != "hello")         # True

Numbers (int and float)

Python compares numeric values across types. An integer and a float with the same numeric value are considered equal.

print(10 != 20)      # True
print(10 != 10)      # False
print(10 != 10.0)    # False  (int vs float, same value)
print(0.1 + 0.2 != 0.3)  # True  (floating-point precision issue!)

The last example is a common pitfall. We cover it in the pitfalls section below.

Lists

Two lists are not equal if they differ in length, content, or order of elements.

print([1, 2, 3] != [1, 2, 3])    # False
print([1, 2, 3] != [3, 2, 1])    # True  (order matters)
print([1, 2, 3] != [1, 2])       # True  (different length)
print([1, 2, 3] != [1, 2, 4])    # True  (different content)

Dictionaries

Dictionaries are equal if they have the same key-value pairs. Order does not matter (dictionaries are unordered by definition in terms of equality).

d1 = {"a": 1, "b": 2}
d2 = {"b": 2, "a": 1}
d3 = {"a": 1, "b": 3}
 
print(d1 != d2)  # False  (same key-value pairs)
print(d1 != d3)  # True   (different value for key "b")

None

You can compare any value to None using !=, but there is a better way. See the pitfalls section for why is not None is preferred.

x = None
y = 42
 
print(x != None)  # False
print(y != None)  # True

Booleans

Booleans are a subclass of int in Python. True equals 1 and False equals 0.

print(True != False)   # True
print(True != 1)       # False  (True is 1)
print(False != 0)      # False  (False is 0)
print(True != 2)       # True

!= vs is not: Identity vs Equality

This is one of the most common sources of confusion in Python. The != operator tests value inequality. The is not operator tests identity inequality -- whether two variables refer to different objects in memory.

a = [1, 2, 3]
b = [1, 2, 3]
c = a
 
# Value comparison
print(a != b)       # False  (same content)
print(a != c)       # False  (same content)
 
# Identity comparison
print(a is not b)   # True   (different objects in memory)
print(a is not c)   # False  (same object, c is an alias for a)

Even though a and b contain the same values, they are separate list objects stored at different memory addresses. The != operator says they are equal (because their contents match). The is not operator says they are different objects.

When to use which

SituationUseReason
Comparing values!=You care about the data, not the memory address
Checking for Noneis not NoneNone is a singleton; identity check is correct and faster
Checking for True/Falseis not TrueAvoid accidental matches with truthy/falsy values
Comparing mutable objects by content!=Lists, dicts, sets should be compared by value
# Correct: use "is not" for None checks
value = get_result()
if value is not None:
    process(value)
 
# Correct: use != for value checks
if user_input != "quit":
    continue_loop()

Customizing != with eq and ne

When you create a custom class, Python does not know how to compare instances by default (it falls back to identity comparison). You can define __eq__ and optionally __ne__ to control how == and != behave.

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius
 
    def __eq__(self, other):
        if not isinstance(other, Temperature):
            return NotImplemented
        return self.celsius == other.celsius
 
    def __ne__(self, other):
        result = self.__eq__(other)
        if result is NotImplemented:
            return result
        return not result
 
    def __repr__(self):
        return f"Temperature({self.celsius}C)"
 
t1 = Temperature(100)
t2 = Temperature(100)
t3 = Temperature(50)
 
print(t1 == t2)  # True
print(t1 != t2)  # False
print(t1 != t3)  # True

In Python 3, if you define __eq__, Python automatically generates __ne__ as its logical inverse. You only need to define __ne__ explicitly if you want non-standard behavior. However, defining both is still common practice for clarity.

Key detail: Returning NotImplemented (not NotImplementedError) tells Python to try the comparison from the other operand's side. This is important for interoperability between different types.

Using != in Control Flow

The not equal operator is used throughout Python's control flow structures.

if Statements

status_code = 404
 
if status_code != 200:
    print(f"Request failed with status {status_code}")

while Loops

user_input = ""
while user_input != "quit":
    user_input = input("Enter command (or 'quit' to exit): ")
    if user_input != "quit":
        print(f"Processing: {user_input}")

List Comprehensions

numbers = [1, 2, 3, 4, 5, 3, 2, 1]
without_threes = [n for n in numbers if n != 3]
print(without_threes)  # [1, 2, 4, 5, 2, 1]

filter()

data = ["apple", "", "banana", "", "cherry"]
non_empty = list(filter(lambda s: s != "", data))
print(non_empty)  # ['apple', 'banana', 'cherry']

Dictionary Comprehension

scores = {"Alice": 85, "Bob": 0, "Carol": 92, "Dave": 0}
active_scores = {k: v for k, v in scores.items() if v != 0}
print(active_scores)  # {'Alice': 85, 'Carol': 92}

Common Pitfalls

Pitfall 1: Floating-Point Comparison

Floating-point arithmetic produces tiny rounding errors. Direct != comparison can give unexpected results.

# This is True due to floating-point precision
print(0.1 + 0.2 != 0.3)  # True
 
# The actual value
print(f"{0.1 + 0.2:.20f}")  # 0.30000000000000004441

Solution: Use math.isclose() for float comparisons.

import math
 
a = 0.1 + 0.2
b = 0.3
 
# Wrong way
if a != b:
    print("Not equal (but they should be)")  # This prints
 
# Right way
if not math.isclose(a, b):
    print("Not equal")
else:
    print("Close enough to be equal")  # This prints

You can control the tolerance with rel_tol (relative) and abs_tol (absolute) parameters:

math.isclose(a, b, rel_tol=1e-9)   # default relative tolerance
math.isclose(a, b, abs_tol=1e-12)  # absolute tolerance

Pitfall 2: None Comparison with !=

Using != with None works, but it is not the Pythonic way. None is a singleton object in Python -- there is only one None in memory. Use is not for identity comparison.

value = None
 
# Works but not recommended
if value != None:
    print("Has a value")
 
# Correct and idiomatic
if value is not None:
    print("Has a value")

The is not None form is also slightly faster because it compares memory addresses instead of calling __eq__.

Pitfall 3: != with Different Types

Comparing objects of incompatible types with != returns True without raising an error. This can hide bugs.

print(42 != "42")       # True  (int vs string)
print([1, 2] != (1, 2)) # True  (list vs tuple)
print(1 != True)         # False (bool is subclass of int)

If you expect type consistency, add explicit type checks.

Chaining Comparisons with !=

Python supports chaining comparison operators. But != chaining does not mean what you might expect.

a, b, c = 1, 2, 1
 
# This is equivalent to: (a != b) and (b != c)
print(a != b != c)  # True
 
# It does NOT mean "all three are different from each other"
# a != c is never checked!
print(a != c)  # False -- but the chain above was True

The expression a != b != c translates to (a != b) and (b != c). Python checks consecutive pairs only. It does not check a != c. If you need to verify that all values in a group are distinct, use a set:

values = [1, 2, 1]
all_different = len(values) == len(set(values))
print(all_different)  # False

Real-World Example: Data Filtering with Pandas

The != operator is used heavily in pandas for filtering rows from DataFrames.

import pandas as pd
 
df = pd.DataFrame({
    "product": ["Widget", "Gadget", "Widget", "Doohickey", "Gadget"],
    "status": ["active", "discontinued", "active", "active", "discontinued"],
    "price": [9.99, 14.99, 9.99, 24.99, 14.99]
})
 
# Filter out discontinued products
active_products = df[df["status"] != "discontinued"]
print(active_products)

Output:

     product  status  price
0     Widget  active   9.99
2     Widget  active   9.99
3  Doohickey  active  24.99

You can combine multiple != conditions:

# Filter rows where status is not "discontinued" AND price is not 9.99
filtered = df[(df["status"] != "discontinued") & (df["price"] != 9.99)]
print(filtered)

For more complex filtering -- especially when exploring unfamiliar datasets -- typing out boolean conditions for every column gets tedious. PyGWalker (opens in a new tab) lets you filter and explore pandas DataFrames through a visual drag-and-drop interface, similar to Tableau. Instead of writing df[df["column"] != value] repeatedly, you set filters interactively and see results instantly. It works directly inside Jupyter notebooks:

import pygwalker as pyg
 
# Open an interactive visual explorer for your DataFrame
walker = pyg.walk(df)

This is especially useful when you need to apply multiple inequality filters across several columns and want to see the distribution of remaining data in real time.

FAQ

What does != mean in Python?

The != operator is the not equal (inequality) operator in Python. It compares two values and returns True if they are different, False if they are the same. For example, 5 != 3 returns True and 5 != 5 returns False.

What is the difference between != and is not in Python?

The != operator compares values -- it checks whether two objects have different content. The is not operator compares identity -- it checks whether two variables point to different objects in memory. Use != for value comparisons and is not for checking against None or other singletons.

Can you use the not equal sign in Python?

No, the mathematical symbol =/= is not valid Python syntax. Python uses != as the not equal operator. Earlier versions of Python (Python 2) also supported <>, but that was removed in Python 3. Always use !=.

Why does 0.1 + 0.2 != 0.3 return True in Python?

This is a floating-point precision issue, not a Python bug. Computers store decimal numbers in binary, which causes tiny rounding errors. The expression 0.1 + 0.2 evaluates to 0.30000000000000004, not exactly 0.3. Use math.isclose(0.1 + 0.2, 0.3) for reliable float comparisons.

How do I check if a variable is not None in Python?

Use the identity operator: if value is not None:. While value != None also works, is not None is the recommended Pythonic idiom because None is a singleton object and identity comparison is both more correct and faster.

Conclusion

The != operator is one of the most frequently used comparison operators in Python. It compares values for inequality across all built-in types -- strings, numbers, lists, dictionaries, booleans, and None. For custom classes, you control its behavior through the __eq__ and __ne__ dunder methods.

The key distinctions to remember: use != when comparing values, use is not when checking identity (especially for None), use math.isclose() when comparing floats, and be careful with chained != comparisons since Python only checks consecutive pairs.

📚