Python Operators Explained With Examples You Will Use in Real Code

Stackademic

Arithmetic, comparison, logical, and identity operators in Python—precedence, short-circuit rules, and interview pitfalls in one guide.

Python operators are the symbols and keywords that let you compute values, compare data, and control flow. If you searched for operators in Python, you probably want a practical map of what each operator does, how precedence works, and the mistakes that trip up beginners in interviews and code reviews.

The quick map

Python groups operators into a few families:

FamilyExamplesTypical use
Arithmetic+, -, *, /, //, %, **Numbers, some sequences
Comparison==, !=, <, >, <=, >=Branching, sorting keys
Logicaland, or, notCombining conditions
Bitwise&, |, ^, <<, >>Flags, low-level math
Assignment=, +=, -=, …Updating variables
Membershipin, not inCollections and strings
Identityis, is notSame object in memory

The sections below focus on the ones that show up most often in day-to-day Python and in technical interviews.

Arithmetic operators

Addition and subtraction work as you expect for integers and floats. With strings, lists, and tuples, + concatenates or combines sequences when types match.

total = 10 + 3        # 13
label = "py" + "thon" # "python"

Multiplication repeats sequences: "ha" * 3 becomes "hahaha".

True division (/) always returns a float in Python 3, even when the result is whole:

7 / 2   # 3.5
8 / 4   # 2.0  (still a float)

Floor division (//) drops the fractional part toward negative infinity, not toward zero:

7 // 2   # 3
-7 // 2  # -4  (not -3)

Modulo (%) returns the remainder. It is related to floor division: a == (a // b) * b + (a % b) for non-zero b.

Exponentiation (**) is right-associative: 2 ** 3 ** 2 is 2 ** (3 ** 2), not (2 ** 3) ** 2.

Comparison operators and chaining

Comparisons return True or False. Python allows chained comparisons, which read naturally and avoid repeating a variable:

x = 15
if 10 < x <= 20:
    print("in range")

That is equivalent to 10 < x and x <= 20, but easier to read.

Watch out when comparing floats with ==; use math.isclose when you care about tolerance.

Logical operators: and, or, not

Python uses the words and, or, and not instead of && and ||. They are short-circuiting: the right-hand side is not evaluated if the result is already decided.

def side_effect():
    print("called")
    return True

False and side_effect()  # prints nothing
True or side_effect()    # prints nothing

A common interview question: what is the value of [] or [1]? The expression returns the first truthy operand, or the last one if all are falsy. That is why x = user_name or "guest" works.

Truthy and falsy values matter everywhere:

  • Falsy: None, False, zero numbers, empty "", [], {}, set()
  • Most other objects are truthy

Assignment and walrus (:=)

Simple assignment binds a name to an object. Augmented assignment (+=, -=, …) updates in place for mutable types when the operation supports it.

The walrus operator (:=) assigns inside an expression, useful in comprehensions and while loops:

while (line := input().strip()) != "quit":
    process(line)

Membership: in and not in

Use in to test whether a value appears in a collection or substring:

"py" in "python"      # True
3 in {1, 2, 3}        # True

For dicts, in tests keys, not values. Use .values() or iterate items when you need values.

Identity: is versus ==

== checks value equality (often via __eq__). is checks whether two names refer to the same object in memory.

Use is for singletons like None:

if value is None:
    ...

Never write if value == None: in production code; use is None.

Small integers and short strings may be interned, so is can accidentally appear to work for == cases—do not rely on that.

Bitwise operators (when you actually need them)

Bitwise &, |, ^, and shifts appear in permissions, protocol flags, and packed binary formats. For everyday application code you may never touch them, but interviews still ask:

flags = READ | WRITE
can_read = bool(flags & READ)

Operator precedence (what binds first)

When in doubt, add parentheses. Rough order from tight to loose:

  1. Parentheses, subscripts, calls
  2. Exponentiation (**)
  3. Unary +, -, not
  4. *, /, //, %
  5. +, -
  6. Comparisons, membership, identity
  7. not
  8. and
  9. or

The official table lives in the Python language reference; memorizing every row is less useful than knowing that comparisons chain and logical operators are lower precedence than comparisons.

Practical pitfalls

Mutating while iterating — Using += on a list inside a loop that walks the same list can skip elements. Build a new list instead.

Default mutable arguments — def f(x=[]) shares one list across calls. Use None and assign inside the function.

Using is for strings or small ints — Works sometimes due to interning; wrong tool for equality.

Forgetting that / is float division — Use // when you need an integer result.

FAQ

What is the difference between / and // in Python?
/ performs true division and returns a float. // performs floor division and returns an integer type when both operands are integers.

Does and return a boolean?
Not always. It returns the first falsy operand or the last operand if all are truthy. Same idea for or with truthy values.

Are == and is interchangeable for strings?
No. Use == for string content; reserve is for identity checks like is None.

What operator has the highest precedence?
Parentheses override everything. Among unary and binary operators, exponentiation binds tighter than multiplication, which binds tighter than addition.

Learning operators is not about memorizing every edge case—it is about reading expressions confidently and choosing the right tool (== vs is, / vs //, and/or short-circuiting) when you write and review Python code.

Unary and ternary forms

Unary plus and minus coerce to numeric types when possible: - on a string raises TypeError. The not operator negates truthiness without changing the underlying object.

Python’s conditional expression (value_if_true if condition else value_if_false) is often called a ternary operator even though it uses keywords:

status = "adult" if age >= 18 else "minor"

That reads clearer than nested if blocks when assigning one of two literals.

Slicing and subscript operators

Subscripts use [] with integers, slices, or slice objects. Slice syntax start:stop:step relies on __getitem__ on sequences and does not call __iadd__ or other arithmetic operators—keep slicing separate in your mental model when debugging off-by-one errors.

@ matrix multiplication

Python 3.5 added @ for matrix multiplication (PEP 465), primarily for NumPy-like libraries. In plain Python without NumPy, you rarely see @, but interviews in data roles may mention it alongside * for element-wise product in array libraries.

F-strings and operator-like formatting

While not operators, f-string {expr!r} and format specifiers interact with expressions that use operators inside braces. Parentheses inside f-strings disambiguate where { ends—another reason precedence tables matter when logging computed values.

Teaching pattern for study groups

When mentoring junior developers, assign a short kata: rewrite nested if chains using chained comparisons and in membership, then refactor boolean flags with any() / all() built-ins (which also short-circuit). That connects operator semantics to readable control flow better than flash cards alone.