Python not Operator: The Complete Guide to Logical Negation

Python’s logical operators are totally lame... not!
Now that I’ve gotten that lame 90s joke out of my system, let’s talk about not, a powerful operator for negating logical expressions in Python. The not operator brings you a topsy-turvy view of the world: True becomes False, False becomes True, and with it, your favorite operators (is, in, etc.) behave like it’s “Opposite Day.” You’ll see not throughout Python code, so it’s worth paying attention to.
This article focuses on the Python not operator. You’ll learn what it is, how to add it to conditional statements, and how it compares to similar constructs like != and ~. It’s a foundational concept with plenty of intricacies, so let’s get going.
The not Keyword as a Boolean Operator
The not keyword is a logical operator in Python. It gives the opposite Boolean values: True becomes False, and False becomes True:
The not operator returns a Boolean value always. It often helps simplify logic so that you can write cleaner code for conditional statements and loops. For instance, this if statement prints a denied entry message if the user does not have permission:
The user_has_permission variable will either be True or False, and not negates the Boolean variable.
not Operator in Python: Truthiness
While the not operator frequently appears with Boolean expressions, it can also show up when evaluating truthiness in Python. Python classifies values as “truthy” or “falsy” to extend the concept of True and False beyond traditional Booleans. Common examples of “falsy” values include:
False
None
0, 0.0, or 0j
[], {}, (), or set()
"" (empty string)
range(0)
Just about everything else is truthy.
Use the not operator to catch empty lists or strings, zero-valued integers or floats, nulls (None), or other falsy values. Here’s an example:
Note that Python evaluates if not list_of_values as True when list_of_values is empty because empty lists are falsy. This syntax is generally preferred over checking the length of a list (if len(list_of_values) == 0) for readability and to be more Pythonic.
Using the not Operator in Statements
You’ve already seen a few examples of not in conditional statements. This is the primary place to use the not logical operator, so let’s dive even deeper and explore not with while loops as well.
Conditional Statements (if Statements)
Conditional statements control program flow by executing a portion of code only when a particular statement evaluates to True. Classically, Python uses the if, elif, else keywords to establish logical flow, but more recent versions of Python (3.10+) now allow match for pattern-based branching. Incorporate the not operator into these flows to negate statements.
In the following Python snippet, the if conditional checks the truthiness of the user_input variable, and the elif conditional determines if the input is numeric. Once the code verifies a valid input, it safely converts to an integer and adds the inputted amount to a running total.
The match statement allows you to compare against multiple patterns in a defined order. In the same spirit as the CASE statement in SQL, match evaluates each case sequentially and executes at the first matching branch. You typically won’t use the not operator within the case patterns themselves; instead, you handle edge cases like empty or invalid values with guard clauses before the match block begins:
while Loops
In Python, while loops continuously execute code until a condition becomes false. Truthiness comes in particularly handy here, and you’ll typically add not to loop conditions to check against flags, collections, and search conditions. The not operator helps the loop syntax read more like natural language, such as “while not finished” or “while not empty,” and it often appears in real-world problems to wait until something exists.
The queue in code below begins as an empty list, not queue evaluates to True, so the loop runs. Inside the loop, task_1 adds to the queue, making the list non-empty (truthy). not queue becomes False, causing the loop to stop.
Combining not with Other Logical Operators and Complex Conditions
As you add not to your Python code, you’ll eventually want to pair it with other operators like and, or, is, or in to build more complex statements. The not operator works well alongside these other Python constructs, but there are a few important nuances to keep in mind.
Logical Operators: and, or
The logical operators and and or allow you to combine multiple conditions. and requires both conditions to be True, while or requires at least one condition to be True. Here’s an example of and and or with Boolean values:
Like you saw for conditionals, the not operator negates the truth value of an expression. You can use it to negate individual expressions or grouped conditions:
Operator Precedence
Operator precedence dictates the order Python evaluates operators in an expression. You may have heard of PEMDAS for arithmetic expressions. This is the same idea, just extended to all operators in Python.
For logical operators:
nothas higher precedence thanandandhas higher precedence thanor
This is what you can expect in Python:
Comparison operators (==, !=, <, >, and so on) have higher precedence than logical operators. Python evaluates them before not, and, or or. This means that Python interprets expressions like not x > 4 as not (x > 4), with the comparison happening first.
You can avoid confusion in this code by switching to x ≤ 4. For other cases, add parentheses. Parentheses override any default precedence. They’re always evaluated from inside out and should be used to make intent explicit and improve readability.
Compound Forms: not in and is not
The not operator naturally complements two related operators to form not in and is not. These are compound operators that make Python code easier to understand and are generally preferred over negating statements involving in or is (e.g. not (x in y) or not (x is y)).
The not in membership operator gives you the ability to cleanly check if an item is absent from a collection (string, list, dictionary, set, etc.). It’s the opposite of the in operator, and here’s an example:
In Python, is not is an identity operator. It determines if two variables are not the same object in memory, and you’ll often use it to check against None.
Be sure not to confuse the inequality operator != with the identity operator is not. Use != to compare values and reserve is not to test identity. For instance:
The a and b lists have the same contents, so a != b gives False; however, a and b are stored at different memory locations, so a is not b returns True.
not vs Similar Operators Comparison Table
Operator | Operator Type | What It Does | Applies To | Common Use Case | Example |
|---|---|---|---|---|---|
| Logical | Reverses truthiness of an expression | Any expression (truthy/falsy values) | Checking emptiness or negating conditions |
|
| Membership | Checks a value is not contained in a collection | Strings, lists, sets, dicts | Excluding values |
|
| Identity | Checks whether two objects are not the same object | Objects, None | None checks, identity comparisons |
|
| Comparison | Checks whether two objects are not equal | Numbers, strings, comparable objects | Value inequality checks |
|
| Bitwise | Flips all bits of an integer; in pandas/NumPy, flips Boolean values elementwise | Integers; Boolean arrays (pandas/NumPy) | Low-level bit manipulation; negating masks in pandas/NumPy |
|
Best Practices and Common Pitfalls
You’ve already seen a few gotchas in this article (misunderstanding operator precedence, confusing != with is not), and here are a couple more. When using the not operator, make sure not to make these mistakes.
Creating Double Negatives in Boolean Logic
The not operator gives you a powerful new way to write conditionals and loops, but be sure not to overuse it. Try to simplify the conditions as much as possible. Like the English language, that means avoiding double negatives.
Both of the following conditional statements are logically equivalent, but the second one is preferred since it’s clearly easier to understand:
Confusing not (logical operator) with ~ (bitwise operator)
If you’re confusing not for ~, chances are you’re using the pandas or NumPy library. In those libraries, ~ works elementwise on series, dataframes, and arrays, oftentimes used to invert each entry of a Boolean mask. Here’s a snippet that determines if each department value is missing, then flips those Booleans with ~:
Say you attempt to use the not operator with a mask instead:
not cannot operate on a pandas Series because a Series does not reduce to a single Boolean value. For example, df[].isna() returns a Series of True and False values, which raises a ValueError when used with not:
ValueError: The truth of a Series is ambiguous.
However, do continue to use the not operator with single-valued Booleans or when checking the truthiness of a single value:
Wrapping Up
In Python, not is a logical operator to help you flip Booleans and negate truthiness. You’ll find it in conditional statements, paired with other logical operators (and, or), and in compound operators (not in, is not). To keep it straight from other negation operators, remember that not works logically, for single Boolean values or single expressions.
Take your not knowledge to the next level by interacting with the AI Tutor. Here’s a prompt to get you started:
- Python Print New Line: Methods, Examples, and Best Practices
- Python Exponent: 5 Methods for Exponentiation + Applications
- Python Modulo Operator (%): Complete Guide with Examples
- Python Division: Operators, Floor Division, and Examples
- Python Switch Statement 101: Match-case and alternatives
- Python glob Module: File Pattern Matching Explained
- Binary search in Python 101: Implementation and use cases
- Hashmaps in Python: Master Implementation and Use Cases
- Python Nonlocal Keyword Explained by Our Experts
- Encapsulation in Python: All You Need to Know
Kimberly Fessel