Operators

Learn about the different operators in Python and how to use them.

Ali Berro

By Ali Berro

12 min read Section 4
From: Python Fundamentals: From Zero to Hero

Operators

Python offers a plethora of operators, grouped into categories:

  • Arithmetic
  • Assignment
  • Comparison
  • Logical
  • Identity
  • Membership
  • Bitwise

Each one of these categories serve a different purpose. In this section, we will be exploring the first four categories, then whenever each one is needed, we will include it in its own section.

Arithmetic Operators

Creating variables just to hold values is quiet boring, we need some way to manipulate them. This is where operators shine, they let us perform well.. operations. Arithmetic operators deal mostly with numeric values. The four basic operators are:

  • + which adds two numbers
  • - which subtracts the first number from the second
  • * computes the product of two values
  • / division which divides the first number by the second
basic-arithmetic-example.py
x = 1 + 2
y = 3 * 4
z = y / x - 1
print(x, y, z)

Note

The division operator always yields a float. Dividing by zero is not allowed and will raise a ZeroDivisionError.

We are left with:

  • ** which raises the first number to the power of the second
  • % which returns the remainder after division of the first number by the second
  • // which performs floor division, i.e. it goes down to the nearest integer

The ** operator raises the first number to the power of the second.

power-example.py
print(2 ** 3) #8
print(3 ** 2) #9
print(10 ** 0) #1
print(10 ** -1) #0.1

Next in line is the // floor division. We can think of it as an elevator down-stairs. This behaves like the division, but if the result has a decimal part (wasn’t divisible), it goes down to the nearest integer.

floor-division-example.py
print(5 // 2) #2
print(4 // 2) #2
print(8 // 3) #2
print(4 // 5) #0
print(1.2 // 1) #1
print(-0.5 // 1) #-1
print(-1.5 // 1) #-2

The yielded type may not always be an integer. This is something that few people know about, if any of the numbers is a float, the result would be a float (integer with a .0 at the end of it).

floor-division-example2.py
print(4 // 2) #2
print(4.0 // 2) #2.0
print(4 // 2.0) #2.0
print(4.0 // 2.0) #2.0

We also have the modulo operator %, which takes two numbers a and b and returns the remainder after division of a by b.

modulo-example.py
print(5 % 2) #1
print(14 % 4) #2
print(28 % -5) #-2

The modulo operator always yields a negative value, if the second number is negative.

modulo-example2.py
print(5 % 3) #2
print(-5 % 3) #1
print(5 % -3) #-1
print(-5 % -3) #-2

There is a relation between the floor division and the modulo operator, which is:

x=(x//y)y+(x%y)x = (x // y) * y + (x \% y)

so

x%y=x(x//y)yx \% y = x - (x // y) * y

Common Type Conversion

When we say that an arithmetic operation uses the phrase: “The numeric arguments are converted into a common type”, this means that the built-in operators work as follows:

  • If either arguments is a complex, the other is converted to complex.
  • If either is a floating number, the other is converted to a floating number.
  • If either is a integer, the other is converted to a integer.
  • Otherwise, both must be integers and conversion is not necessary.

Addition, subtraction, multiplication, division, floor division, modulo and power obey the previous rule. While the floor division yields an integer, the value is converted to the common type.

Assignment Operators

An assignment operator = is used to bind (or rebind) a value to a variable. This is done by evaluating the right-hand side of the assignment operator and then binding the value to the left-hand side.

assignment-operator-example.py
x = 10
y = 20
z = 30
print(x) #10
print(y) #20
print(z) #30
x = 40 #rebind
print(x) #40

We can also use the assignment operator to bind multiple variables to a single value.

assignment-operator-example2.py
x = y = z = 10
print(x) #10
print(y) #10
print(z) #10

Augmented Assignment Operators

Augmented assignment operators are a shorthand for the assignment operator. They are used to perform an operation and then assign the result to the left-hand side.

augmented-assignment-operator-example.py
x = 10
x += 10
print(x) #20

x += 10 is equivalent to x = x + 10. In general x op= y is equivalent to x = x op y, where op is the operator.

Following is a list of augmented assignment operators: +=, -=, *=, @=, /=, //=, %=, **=, >>=, <<=, &=, ^=, |=

augmented-assignment-operator-example2.py
x = 10
x -= 2 #x = x - 2
print(x) #8
x *= 10 #x = x * 10
print(x) #80
x /= 3 #x = x / 3
print(x) #26.666666666666668
x //= 2 #x = x // 2
print(x) #13.0
x %= 10 #x = x % 10
print(x) #3.0

Comparison Operators

Python supports the usually comparison operators:

  • == Equal
  • != Not equal
  • > Greater than
  • < Less than
  • >= Greater than or equal
  • <= Less than or equal

All of these operations have the same precedence level. Comparison operators always return a boolean value True or False.

comparison-operators-example.py
x = 10
y = 20
z = 30
print(x == y) #False
print(x != y) #True
print(x > y) #False
print(x >= y) #False
print(x <= y) #True
print(x < z) #True
print(x > z) #False
print(x >= z) #False
print(x <= z) #True

The equality comparison (== and !=) checks if two values have the same identity.

Note

One can get the identity of an object using the id function.

By default, an order comparison (<, >, <=, and >=) is not provided on all types, so writing something like None < 2 will raise a TypeError.

If we were using a mix of booleans, integers, or floats, then they are converted to a common type, and then the comparison is performed. If we have two strings, then the comparison is performed lexicographically.

Info

Lexicographical comparison is the comparison of strings based on the dictionary order of the characters. It is performed by comparing the Unicode code points of the characters in the strings.

Comparison Chaining

Comaprison operators can be chained together similar to mathematical expressions. x<yzx < y \geq z is equivalent to x<yx < y and yzy \geq z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

Comparison chaining isn’t limited to operators of the same nature (i.e. only greater thans, or only less thans), it can be used with any combination of operators.

comparison-chaining-example.py
x = 10
y = 20
z = 30
print(x < z > y) #True
print(x < y != z) #True
print(x == y == z) #False
print(x != y < z) #True

Saying y is evaluated once is important, suppose that y is a function call, and it has a side effect, such as printing a value to the console. If y is evaluated twice, the side effect will be executed twice. In an expression which contains comparison chaining, the evaluation stops once we reach a False value.

print(1 != print("Hello") != 2) #True, prints Hello once
print(1 != print("Hello") && print("Hello") != 2) #True, prints Hello twice
print(1 == 2 == print("Hello")) #False, since we have short-circuiting, print("Hello") is not evaluated

Logical Operators

Python supports the following logical operators:

  • not
  • and
  • or

The operator not yields True if its argument is False, False otherwise.

The expression x and y first evaluates x; if x is False, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is True, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Truth Table

xyx and yx or ynot x
FalseFalseFalseFalseTrue
FalseTrueFalseTrueTrue
TrueFalseFalseTrueFalse
TrueTrueTrueTrueFalse
logical-operators-example.py
print(not True) #False
print(not False) #True
print(True and False) #False
print(True and True) #True
print(True or False) #True
print(False or False) #False

These operators are not restricted to only booleans, they can take any value and depending on the truthiness of the value, the operator will return the value. The returned value is not necessarily a boolean, but rather return the last evaluated argument. This is sometimes useful if for instance you want to set a default value for a variable if it is not set.

logical-operators-example.py
print(True and 1) #1
print(False and 1) #False
print(True or 1) #True
print(False or 1) #1
print(not 1) #False
print(not 0) #True
logical-operators-example2.py
name = ""
print(name or "Guest") #Guest
name = "Ali"
print(name or "Guest") #Ali

In the first case, the expression name or "Guest" yields the desired value, since name is an empty string, it will evaluate the second argument and return it. In the second case, the expression name or "Guest" will evaluate the first argument and return it, since name is not an empty string.

An important thing to keep in mind is that both operators and and or have short-circuiting behavior. This means that the second argument is not evaluated if the first argument is enough to determine the result.

  • For the and, if the first argument is False, the second argument is not evaluated and the result is False.
  • For the or, if the first argument is True, the second argument is not evaluated and the result is the first argument.
short-circuiting-example.py
print(0 and True) #0 (since 0 is Falsy)
print(3 or False) #3 (since 3 is Truthy)

Precedence and Associativity

Operators have a precedence and associativity. The precedence is the order in which the operators are evaluated. The associativity is the order in which the operators are grouped.

The following table shows the precedence of the operators in Python.

OperatorDescriptionAssociativity
(expressions) [expressions] {key: value} {expressions}Parentheses, lists, dictionaries, setsLeft to right
x[index] x[index:index] x(arguments)Indexing, slicing, function callsLeft to right
await xAwait expressionLeft to right
**PowerRight to left
+x -x ~xUnary plus, unary minus, bitwise NOTRight to left
*, @, /, //, %Multiplication, multiplication by matrix, division, floor division, moduloLeft to right
+, -Addition, subtractionLeft to right
<< >>Bitwise left shift, bitwise right shiftLeft to right
&Bitwise ANDLeft to right
^Bitwise XORLeft to right
|Bitwise ORLeft to right
in not in is is not < > <= >= != ==Membership, identity, comparisonLeft to right
notLogical NOTRight to left
andLogical ANDLeft to right
orLogical ORLeft to right
if-elseConditional expressionRight to left
lambdaLambda expression
:=Assignment expressionRight to left

The first row in the table is the highest precedence, the last row is the lowest precedence. As we can see there are some columns with multiple operators, these operators have the same precedence. But in an expression with multiple operators having the same precedence, the associativity is used to determine the order of evaluation.

Note

We have added all the operators here, even the ones that we didn’t mention in this section, nor the previous ones. This is to give you a complete picture of the operators in Python.

Exercises

Exercise 1: Assignment Operator

Write a program which creates three variables x, y and z, and assigns them the values 10, 20 and 30 respectively. Then print the values of x, y and z.

Answer:
x = 10
y = 20
z = 30
print(x, y, z)

Exercise 2: Find the output

What is the output of the following code?

x = 10
y = 3
print(x + y * 2)
Answer:

The output of the code is 16.

Exercise 3: Find the output

What is the output of the following code?

a = 7
a += 3
a *= 2
print(a)
Answer:

The output of the code is 20.

Exercise 4: Find the output

What is the output of the following code?

print(True and False or True)
print(True and (False or True))
Answer:

The output of the code is True and True.

Exercise 5: Logical Operators

Explain why True or anything always returns True, but False and anything always returns False.

Answer:

Because the or operator returns True if either of the arguments is True, and the and operator returns False if either of the arguments is False.

Course Progress

Section 4 of 17

Back to Course