Operators in Python
By the Syncfusion DevTutorials team · Last updated
The symbols that do the work in Python: arithmetic, comparison, assignment shortcuts, and, or, is, in, bitwise, the walrus operator, and precedence.
A calculator has buttons: plus, minus, times, divide.
You press a button, give it two numbers, and it gives you an answer.
Python works the same way, and the buttons are symbols you type.
Four familiar buttons
maths = 78
science = 85
print(maths + science)
print(maths - science)
print(maths * 2)
print(maths / 2)
Each symbol took two numbers and produced one answer. Those symbols are called operators.
Python has more of them than a calculator does. Some compare two values. Some ask yes-or-no questions. One checks whether something is inside a list. They all follow the same shape: give it values, get an answer back.
What You Will Learn
In this lesson, you will learn:
- The seven arithmetic operators, including the two that surprise people
- How to compare two values and get
TrueorFalse - Shortcuts like
+=that update a variable in place and,orandnot, and why Python sometimes stops reading halfway- A one-line way to choose between two values
- The difference between "the same value" and "the same object"
- How to check whether something is inside a list or a piece of text
- The operators that work on the bits inside a number
- The walrus operator
:=, which stores a value and uses it at once - The order Python applies all of these in, and how brackets take control
Do not worry about memorizing every operator right away. Focus on understanding what each group does and when to use it.
Introduction to Operators
An operator is a symbol that takes values and produces a new value.
What Are Operators?
An operator is a symbol that takes one or two values and produces a new value.
For example, + takes two numbers and produces their total. > takes two numbers and produces True or False.
Why Operators Are Used
Without operators a program could only store values and print them back. Operators are what let it work something out.
Working something out, not just storing it
total_marks = 450
subjects = 6
average = total_marks / subjects
print("Average:", average)
print("Passed:", average >= 35)
Two operators did real work here. / found the average. >= turned that average into a yes-or-no answer.
Operands and Expressions
The values an operator works on are called operands. The whole thing — operands and operator together — is an expression.
In 78 + 85, the numbers 78 and 85 are the operands, + is the operator, and 78 + 85 is the expression.
Every expression produces a value, so an expression can be used inside a bigger expression.
Small expressions inside a bigger one
maths = 78
science = 85
english = 60
print((maths + science + english) / 3)
Python worked out the brackets first, got 223, then divided by 3.
Types of Operators in Python
Python operators are grouped by what they do. Some perform calculations, some compare values, and some help make decisions. Here is the full list, and you will meet every group in this lesson.
| Group | Symbols | What they do |
|---|---|---|
| Arithmetic | + - * / // % ** | do sums |
| Comparison | == != > < >= <= | compare two values |
| Assignment | = += -= *= /= //= %= **= | store and update |
| Logical | and or not | combine yes-or-no answers |
| Identity | is is not | ask whether two names hold the same object |
| Membership | in not in | ask whether a value is inside something |
| Bitwise | & | ^ ~ | work on the bits inside a number |
| Walrus | := | store a value and use it in the same line |
Arithmetic Operators
Arithmetic operators do sums. They are the ones you already know from a calculator, plus a few Python extras.
Addition (+)
+ adds two numbers together, or joins two pieces of text.
Adding
maths = 78
science = 85
print(maths + science)
+ also joins text, which you met in the last lesson. The type of the values decides which job it does.
Subtraction (-)
- subtracts one number from another.
Subtracting
marks = 78
print(100 - marks)
Multiplication (*)
* multiplies two numbers, or repeats text a number of times.
Multiplying
marks_per_test = 25
tests = 4
print(marks_per_test * tests)
* repeats text as well:
Multiplying text
print("-" * 20)
print("ab" * 3)
Division (/)
/ always gives a float, even when the numbers divide exactly.
Division always gives a decimal
print(450 / 6)
print(10 / 2)
print(type(10 / 2))
10 / 2 is 5.0, not 5. This surprises many beginners, and it is on purpose: / gives the exact answer, including any fraction, and Python always shows that answer as a decimal.
Dividing by zero stops the program:
Dividing by zero
subjects = 0
print(450 / subjects)
There is no answer to dividing by zero, so Python stops the program with a ZeroDivisionError. Check for zero before you divide.
Floor Division (//)
// divides and throws away the fraction, giving a whole number.
Division without the fraction
print(17 / 5)
print(17 // 5)
17 / 5 is 3.4. 17 // 5 is 3.
Use // when a fraction makes no sense. You cannot have 3.4 full boxes.
How many full rows of 5?
students = 17
per_row = 5
print("Full rows:", students // per_row)
print("Left over:", students % per_row)
Modulus (%)
% gives what is left over after a division. People usually read it aloud as "mod".
What is left over
print(17 % 5)
print(20 % 5)
17 divided by 5 is 3 with 2 left over, so 17 % 5 is 2. Nothing is left over from 20, so 20 % 5 is 0.
% 2 is the usual way to ask whether a number is even:
Even or odd
for number in [10, 7, 4]:
print(number, "even?", number % 2 == 0)
A leftover of 0 means the number divided exactly, so it is even.
Exponentiation (**)
** raises a number to a power.
Powers
print(2 ** 3)
print(5 ** 2)
print(9 ** 0.5)
2 ** 3 is 2 multiplied by itself 3 times, which is 8. A power of 0.5 is the square root, so 9 ** 0.5 is 3.0.
Arithmetic Expressions
Put them together and you have a real calculation.
A percentage, start to finish
TOTAL_POSSIBLE = 600
scored = 489
percent = scored / TOTAL_POSSIBLE * 100
print("Percent:", round(percent, 1))
print("Whole part:", int(percent))
| Operator | Name | Example | Result |
|---|---|---|---|
+ | add | 78 + 85 | 163 |
- | subtract | 100 - 78 | 22 |
* | multiply | 25 * 4 | 100 |
/ | divide | 17 / 5 | 3.4 |
// | floor divide | 17 // 5 | 3 |
% | modulus | 17 % 5 | 2 |
** | power | 2 ** 3 | 8 |
Comparison Operators
Comparison operators ask questions about values. The answer is always either True or False.
Equal To (==)
== asks whether two values are the same. Two equals signs, not one.
Asking, not assigning
marks = 78
print(marks == 78)
print(marks == 85)
One = stores a value. Two == ask a question. Mixing them up is the most common beginner mistake, in Python and in most other languages.
Not Equal To (!=)
!= asks whether two values are different.
Asking whether two values differ
marks = 78
print(marks != 85)
print(marks != 78)
Greater Than (>)
> checks whether the first value is larger than the second.
Greater than
print(78 > 35)
print(20 > 35)
Less Than (<)
< checks whether the first value is smaller than the second.
Less than
print(20 < 35)
Greater Than or Equal To (>=)
>= checks whether the first value is larger than or equal to the second.
At least
PASS_MARK = 35
print(35 >= PASS_MARK)
print(34 >= PASS_MARK)
A mark of exactly 35 passes, which is why >= is the right operator for a pass mark and > is not.
Less Than or Equal To (<=)
<= checks whether the first value is smaller than or equal to the second.
At most
print(34 <= 35)
print(35 <= 35)
Comparison Expressions
Comparisons are what decisions are made from.
A comparison used as an answer
PASS_MARK = 35
marks = 78
passed = marks >= PASS_MARK
print("Passed:", passed)
print(type(passed))
Python also lets you chain comparisons, which reads exactly like a mathematics line:
Two comparisons in one
marks = 78
print(35 <= marks <= 100)
35 <= marks <= 100 asks whether the marks sit between 35 and 100. Most languages need two comparisons joined by an and to say this.
Assignment Operators
Assignment operators store values and update variables. The basic = stores a value, and the combined operators like += do an operation and store the result in one step.
Assignment (=)
= puts the value on the right into the name on the left.
Storing a value
marks = 78
print(marks)
Add and Assign (+=)
marks += 5 means marks = marks + 5. It is shorter, and it says "update this" more clearly.
Adding to what is already there
score = 0
score += 10
score += 20
print(score)
Subtract and Assign (-=)
Taking some away
lives = 3
lives -= 1
print(lives)
Multiply and Assign (*=)
Multiplying in place
marks = 40
marks *= 2
print(marks)
Divide and Assign (/=)
Dividing in place
total = 450
total /= 6
print(total)
The answer is 75.0, a decimal, because / always gives a decimal.
Floor Divide and Assign (//=)
Dividing in place, whole numbers only
students = 17
students //= 5
print(students)
Modulus and Assign (%=)
Keeping only the leftover
students = 17
students %= 5
print(students)
Exponent and Assign (**=)
Raising in place
side = 4
side **= 2
print(side)
| Operator | Short for | Example | Result |
|---|---|---|---|
+= | x = x + y | 78 += 5 | 83 |
-= | x = x - y | 3 -= 1 | 2 |
*= | x = x * y | 40 *= 2 | 80 |
/= | x = x / y | 450 /= 6 | 75.0 |
//= | x = x // y | 17 //= 5 | 3 |
%= | x = x % y | 17 %= 5 | 2 |
**= | x = x ** y | 4 **= 2 | 16 |
Logical Operators
Logical operators combine yes-or-no answers into one yes-or-no answer.
and
and returns True only when both conditions on the left and right are True.
Both must be true
maths = 78
science = 85
PASS_MARK = 35
print(maths >= PASS_MARK and science >= PASS_MARK)
print(maths >= PASS_MARK and 20 >= PASS_MARK)
The first line is True because both subjects passed. The second is False because one did not.
or
or returns True when at least one condition on the left or right is True.
One is enough
maths = 78
science = 20
PASS_MARK = 35
print(maths >= PASS_MARK or science >= PASS_MARK)
print(20 >= PASS_MARK or 15 >= PASS_MARK)
not
not reverses a True answer to False, or a False answer to True.
Flipping the answer
passed = True
print(not passed)
print(not 20 >= 35)
Boolean Expressions
Combine them and you can describe a real rule in one line.
A rule written out
maths = 78
science = 85
attendance = 92
PASS_MARK = 35
MIN_ATTENDANCE = 75
promoted = maths >= PASS_MARK and science >= PASS_MARK and attendance >= MIN_ATTENDANCE
print("Promoted:", promoted)
Read it aloud and it is the school rule, word for word.
Short-Circuit Evaluation
Python stops reading as soon as it knows the answer. This is called short-circuit evaluation.
With and, if the left side is False, the whole thing is False, so the right side is never looked at.
The right side is never reached
subjects = 0
if subjects != 0 and 450 / subjects > 50:
print("Average is above 50")
else:
print("No subjects to divide by")
subjects != 0 is False, so Python never works out 450 / subjects. Without that check on the left, the program would stop with a ZeroDivisionError.
This is not a trick. Putting the safe test on the left of an and is how real Python code avoids this kind of error.
Put the test that protects the other one on the left: if subjects != 0 and total / subjects > 50. Python reads left to right and stops early, so the dangerous half never runs.
Conditional Expression (Ternary Operator)
What Is a Conditional Expression?
A conditional expression chooses between two values in one line.
value_if_true if condition else value_if_false
The condition sits in the middle. Read it as a sentence: this value, if the test is true, otherwise that value.
Choosing a value in one line
marks = 78
PASS_MARK = 35
result = "Pass" if marks >= PASS_MARK else "Fail"
print(result)
The same thing written as an if statement takes four lines:
The same choice, the long way
marks = 78
PASS_MARK = 35
if marks >= PASS_MARK:
result = "Pass"
else:
result = "Fail"
print(result)
Both are correct. Use the one-line form when the choice is small enough to read at a glance, and the if statement when there is more to do in each branch.
Identity Operators
Identity operators ask whether two names refer to the exact same object. This is different from checking whether the values inside are equal.
is
is checks whether two names refer to the exact same object.
Same value, different objects
first = [78, 85]
second = [78, 85]
third = first
print(first == second)
print(first is second)
print(first is third)
first == second is True: the two lists hold the same values. first is second is False: they are two separate lists that happen to hold matching values. first is third is True, because third is another name for the very same list.
is not
is not checks whether two names point to different objects in memory.
Not the same object
first = [78, 85]
second = [78, 85]
print(first is not second)
Identity vs Equality
Think of it like this: two names can point at two different boxes that hold the same things, or at one single box with two labels. == compares what is inside the boxes. is asks whether there is only one box.
Why it matters: if two names point at the same list, changing it through one name changes what you see through the other.
One list, two names
first = [78, 85]
third = first
third.append(60)
print(first)
print(third)
You appended to third and first changed too, because there was only ever one list.
Comparing Object Identity
The one place you should always use is is None.
The right way to test for None
remark = None
print(remark is None)
print(remark is not None)
A running Python program has only one None, so is None is exactly the right question. It is also the form every Python programmer writes, so other readers expect it.
Use == to compare values, which is almost always what you want. Use is only for None, or when you really are asking whether two names point at one object.
Membership Operators
Membership operators ask whether a value exists inside a collection, like a list, tuple, or string. They give True or False as the answer.
in
in checks whether a value exists inside a collection.
Is it in the list?
marks = [78, 85, 60]
print(78 in marks)
print(90 in marks)
not in
not in checks whether a value does not exist inside a collection.
Is it absent?
marks = [78, 85, 60]
print(90 not in marks)
Membership Testing in Strings
With text, in looks for a smaller piece inside a bigger one.
Looking inside text
remark = "Good work this term"
print("work" in remark)
print("Work" in remark)
The second is False because capital and small letters are different characters. Lowercase both sides when the difference does not matter:
Ignoring the capitals
remark = "Good work this term"
print("work" in remark.lower())
print("WORK".lower() in remark.lower())
Membership Testing in Lists, Tuples, Sets, and Dictionaries
in works the same way on every kind of collection. On a dictionary it checks the keys.
The same question, four kinds of collection
marks_list = [78, 85, 60]
marks_tuple = (78, 85, 60)
marks_set = {78, 85, 60}
report = {"maths": 78, "science": 85}
print(78 in marks_list)
print(78 in marks_tuple)
print(78 in marks_set)
print("maths" in report)
print(78 in report)
The last line is False. On a dictionary, in looks at the keys, and 78 is a value. 78 in report.values() is the question that gives True.
The next two sections cover operators that beginners use less often. You do not need to memorize them right now, but it is useful to know they exist because you may see them in real Python code.
Bitwise Operators
Every whole number is stored as bits: a row of 1s and 0s. Bitwise operators work on those bits one position at a time.
You will not need these often as a beginner. They matter for permissions, flags and some hardware work, so it is worth knowing they exist.
The number 12 is 1100 in bits, and 10 is 1010.
Bitwise AND (&)
& compares the bits of two numbers and keeps only the bits that are 1 in both.
AND on the bits
print(bin(12), bin(10))
print(12 & 10)
print(bin(12 & 10))
1100 and 1010 share a 1 only in the third position, which gives 1000, and that is 8.
Bitwise OR (|)
| compares the bits of two numbers and keeps a bit if it is 1 in either number.
OR on the bits
print(12 | 10)
print(bin(12 | 10))
Bitwise XOR (^)
^ compares the bits of two numbers and keeps a bit only if it is 1 in exactly one of them.
XOR on the bits
print(12 ^ 10)
print(bin(12 ^ 10))
Bitwise NOT (~)
~ flips every bit in a number. For whole numbers this works out as -(n + 1).
Flipping every bit
print(~12)
print(~0)
| Operator | Name | 12 and 10 | Result |
|---|---|---|---|
& | AND | 1100 1010 | 8 |
| | OR | 1100 1010 | 14 |
^ | XOR | 1100 1010 | 6 |
~ | NOT | 1100 | -13 |
& is not and. & works on the bits inside two numbers. and combines two yes-or-no answers. Using one where you meant the other gives an answer that looks almost right.
Walrus Operator
What Is the Walrus Operator?
The walrus operator := stores a value in a name and gives that value back at the same time.
It is called the walrus because := looks like a walrus lying on its side, with two eyes and a tusk.
Assignment Expressions
A normal = line does its job but gives nothing back to the rest of the line. := is different: it stores the value and hands it back, so you can use it straight away.
Store it and use it at once
remark = "Good work this term"
if (length := len(remark)) > 10:
print("Long remark:", length, "characters")
len(remark) was worked out once, stored in length, and used in the test and in the message.
Using the Walrus Operator in Conditions
Without the walrus you have to call the function twice, or add a line above.
The same thing without it
remark = "Good work this term"
length = len(remark)
if length > 10:
print("Long remark:", length, "characters")
Both are fine. The walrus form keeps the value next to the test that uses it.
Benefits of the Walrus Operator
- The work is done once, not twice.
- The name is created right where it is needed.
- The loop or test stays on one line.
Keeping only the marks worth reporting
marks = [78, 20, 85, 12, 60]
good = [doubled for mark in marks if (doubled := mark * 2) > 100]
print(good)
Each mark was doubled once. The doubled value was tested, and the same value was kept.
Use it when it makes a line clearer. A plain extra line above is never wrong.
Operator Precedence
What Is Operator Precedence?
Precedence is the order Python applies operators in when a line has several.
Which operator goes first?
print(2 + 3 * 4)
The answer is 14, not 20. * is applied before +, exactly as in mathematics.
Order of Operator Evaluation
From first applied to last:
| Order | Operators | Group |
|---|---|---|
| 1 | () | brackets |
| 2 | ** | power |
| 3 | -x ~x | sign, bitwise not |
| 4 | * / // % | multiply and divide |
| 5 | + - | add and subtract |
| 6 | & ^ | | bitwise |
| 7 | == != > < >= <= is in | comparisons |
| 8 | not | logical not |
| 9 | and | logical and |
| 10 | or | logical or |
Two things are worth taking from that table. Comparisons happen after all the arithmetic, which is why marks + 5 >= 35 works without brackets. And and happens before or.
Using Parentheses
Brackets beat everything — whatever is inside them is worked out first. They are also the only part of this table nobody has to remember.
Brackets change the answer
print(2 + 3 * 4)
print((2 + 3) * 4)
Same numbers, same operators, different answers: 14 and 20.
Precedence Examples
Here is where precedence quietly changes a result:
and before or
maths = 78
science = 85
attendance = 50
print(maths >= 35 or science >= 35 and attendance >= 75)
print((maths >= 35 or science >= 35) and attendance >= 75)
The first line is True, the second False. Python applied and first, so the first line really asks: did maths pass, or did both science and attendance pass? The brackets in the second line ask the school's actual rule instead.
Nothing was wrong with Python here. The line was ambiguous to a human and precise to Python, so it is exactly the kind of line where brackets help.
When a line mixes and with or, add brackets even where Python does not need them. The brackets cost nothing and they say what you meant.
Common mistakes
Each row is one mistake. The middle column is what you will actually see on screen.
| Mistake | What you see | Why it happens | Fix |
|---|---|---|---|
Using = where you meant == | SyntaxError: invalid syntax | One = stores a value; a test needs two | if marks == 78: |
Expecting / to give a whole number | 10 / 2 shows 5.0 | / always gives a decimal | Use // when the fraction makes no sense |
| Dividing by a value that can be zero | ZeroDivisionError: division by zero | Nothing checked the divisor first | Guard it: if subjects != 0 and ... |
Mixing and with or and no brackets | An answer that is right for Python and wrong for you | and is applied before or | Add brackets around the part you mean |
Using is to compare values | False for two lists that look identical | is asks whether there is one object, not two equal ones | Use == for values; keep is for None |
| Changing a list through a second name | A list you never touched has changed | Both names point at one list | Copy it first: second = first.copy() |
Using & where you meant and | A number instead of True or False | & works on bits inside numbers | Use and for yes-or-no answers |
| Searching text with the wrong case | "Work" in remark is False | Capital and small letters are different characters | Lowercase both sides first |
Expecting in to search a dictionary's values | 78 in report is False | On a dictionary, in looks at the keys | 78 in report.values() |
Forgetting % needs a whole-number mindset | A leftover you did not expect | % gives the remainder, not the share | 17 // 5 is the share, 17 % 5 the leftover |
What to Remember
- An operator takes values and produces a new value. The values are operands; the whole thing is an expression.
/always gives a decimal.//gives the whole part, and%gives what is left over.**raises to a power, and** 0.5is the square root.- One
=stores. Two==ask a question. - Comparisons produce
TrueorFalse, and Python lets you chain them:35 <= marks <= 100. +=and the rest update a variable in place.andneeds both sides;orneeds one;notflips the answer.- Python stops reading as soon as it knows the answer, so the left side of an
andcan protect the right. value_if_true if condition else value_if_falsechooses between two values in one line.==compares values.isasks whether two names point at one object — keep it forNone.inasks whether a value is inside a collection, and on a dictionary it looks at the keys.&|^~work on the bits inside numbers, and are not the same asandandor.:=stores a value and gives it back in the same line.- Brackets beat every rule of precedence, and they say what you meant.
Next: Conditional Statements