How to use Python operators
Python operators help you work with values or operands. They also help with changing them and linking them together. The operators can be logical or arithmetic.
What are Python operators and how do they work?
An operator is a character for an operation. Operators are usually used to link several operands to form a new value. The application of an operator to a single operand modifies it.
The simplest example of Python operators would probably be to join two numbers using the addition operator, which is a plus sign between the numbers. Python evaluates the expression and returns the corresponding value:
1 + 1
Python is special because short words such as “and”, “or”, “is”, “not” or “in” are used as operators in addition to symbols. The combination of operators and operands results in an expression:
1 + 1 == 2
What are the different types of Python operators?
Python knows several classes of operators. They operate on different types of operands and return a certain type of results. Below is an overview of the different types of Python operators:
Classes of Python operators | Explanation | Operands | Result | Operators at a glance |
Arithmetic operators | Combine two numbers to form a new number | Numbers | Number | +, -, *, /, //, %, **, @ |
Comparison operators | Compare two expressions with each other | Expressions | Boolean | <, >, ==, !=, <=, >= |
Logical operators | Combine expressions in a Boolean context | Expressions | Last evaluated expression / Boolean | and, or, not |
Bitwise operators | Manipulate integers as binary sequences | Numbers | Number | <<, >>, &, |, ^, ~ |
Assignment operators | Assign value to a name | Lvalue, Rvalue | - / Evaluated expression | =, :=, +=, -=, *=, etc. |
Identity operators | Determine whether two names refer to the same object | Objects | Boolean | is, is not |
Conditional operator | Returns one of two values depending on a condition | Expression, condition, alternative | Expression / Alternative | ... if ... else ... |
Set operators | Link two sets / Compare sets | Quantities | Quantity / Boolean | &, |, ^, -, <, >, <=, >= |
Membership operators | Testing whether an iterable contains a specific object | Object, Iterable | Boolean | in, not in |
Concatenation operator | Chained sequences | Strings / Lists / Tuples | String / List / Tuple | + |
Index and slice operators | Return one or more elements of an iterable | Iterable, Index / Slice | String / List / Tuple | [], [::] |
Operators are classified according to their “arity”, along with the type of operands and return value. The arity of an operator has nothing to do with “aric”. The term explains how many operands an operator combines. “Binary” operators with two operands are used in most cases. There are also some “unary” operators with only one operand, as well as a “ternary” operator which links three operands:
Operator arity | Number of operands | Example |
---|---|---|
Unary | One operand | not single_value |
Binary | Two operands | left_operand + right_operand |
Ternary | Three operands | some_value if condition else other_value |
What is note operator precedence?
An understanding of operator precedence is fundamental when it comes to using Python operators. The concept comes from arithmetic and is known as “point before dash calculation”. Just to remind you, the expression 3 * 8 + 2 is interpreted as (3 * 8) + 2, not 3 * (8 + 2). As for the plus sign and the multiplication sign, there are precedence rules for all Python operators. Below is an example of an expression with the logical operators “and”, “or” and “not”:
if is_user and is_user_logged_in or is_admin and not login_blocked:
...
It is impossible to know how the individual terms should be put together without knowing the precedence rules for the Python operators involved. Things can get complicated if multiple operators are used in one expression. It is generally better not to rely on a perfect understanding of implicit rules. You should use explicit braces to clarify how the expression’s terms belong together:
if (is_user and is_user_logged_in) or (is_admin and not login_blocked):
...
The same terms grouped differently result in a different statement:
if (is_user and is_user_logged_in or is_admin) and not login_blocked:
...
What are overloaded operators, Dunder methods and Python operator functions?
Some Python operators are used for more than one operation. A prominent example is the plus sign. The plus sign acts as both an addition operator for numbers and a concatenation operator for concatenating sequences such as strings and lists. We add two numbers with the addition operator:
8 + 3 == 11
We concatenate two strings using the same operator:
"Walter" + "White" == "WalterWhite"
We also concatenate lists with the plus operator:
['Jack', 'Jim'] + ['John'] == ['Jack', 'Jim', 'John']
The plus sign’s multifunctionality as an operator reflects a common concept in computer science. You may have heard of “overloaded operators”, which happen when one and the same operator perform different operations depending on the operands’ data type.
How do overloaded operators work in Python? An operator and its operands are interpreted as a cue to a corresponding function. The first operand’s Dunder method is enabled, which receives the other operands as arguments. “Dunder” stands for “double underscore”. Therefore, the plus operator corresponds to the __add__() Dunder method. Objects which implement an __add__() method can be linked with the plus operator. It is up to the object what constitutes the link exactly.
In addition to the Dunder methods, the operator module contains functions which enclose the Python operators’ functionality. For example, “operator.add(a, b)” enables the Dunder method a.__add__(b), which is equivalent to the expression a + b. We’ll list the operator function for each operator when possible throughout the rest of the article. The name of the operator function corresponds to the name of the appropriate Dunder method. You can use this table as a reference for implementing your own operator functionality:
Python operator | Operator function | Dunder method |
---|---|---|
a + b | operator.add(a, b) | a.__add__(b) |
Operators use the infix notation which inserts the operator between the operands, while the functional style uses the prefix notation. Both notations are equivalent:
Notation | Use | Example |
---|---|---|
Infix | Operators | a + b |
Prefix | Functions | + a b / add(a, b) |
Let’s consider an example. We define two numbers and add them to the operator, the operator function and the corresponding Dunder method:
import operator
a = 42
b = 69
assert a + b == operator.add(a, b) == a.__add__(b)
More complex expressions can also be written with operator functions. The combination of the Python addition and equality operators in prefix notation can be found below:
import operator
assert 'Py' + 'thon' == 'Python'
assert operator.eq(operator.add('Py', 'thon'), 'Python')
An overview of Python operators
We will now look into the eleven different Python operator classes.
Arithmetic operators
Python’s arithmetic operators operate on numbers to create a new number. All of these are binary operators except for the unary plus or minus. An overview is outlined below:
Python operator | Meaning | Operator function | Example |
---|---|---|---|
+ | Addition / unary plus | add(a, b) / pos(a) | 5 + 3 == 8 / +8 == 4 + 4 |
- | Subtraction / unary minus | sub(a, b) / neg(a) | 7 - 2 == 5 / -4 == 2 - 6 |
* | Multiplication | mul(a, b) | 2 * 3 == 6 |
/ | “Real” Division | truediv(a, b) | 8 / 2 == 4.0, 7 / 2 == 3.5 |
// | Integer division to next lower integer | floordiv(a, b) | 8 // 2 == 4, 7 // 2 == 3 |
% | Modulus: Integer division’s remaining amount | mod(a, b) | 8 % 2 == 0, 7 % 2 == 1 |
** | Exponentiation | pow(a, b) | 2 ** 3 == 8, 10 ** -1 == 0.1 |
@ | Matrix multiplication | matmul(a, b) | - |
The modulus operation is used by default to determine whether a number is even. This is because an even number divided by two has a remainder of zero. We define a corresponding Python function with the modulus operator:
def is_even(number):
return number % 2 == 0
# test
assert is_even(8) and not is_even(7)
Matrix multiplication requires a package such as NumPy.
Comparison operators
The Python comparison operators indicate how two elements can be ordered with respect to each other. They give a Boolean result and are used especially for sorting algorithms:
Python operator | Meaning | Operator function | Example |
---|---|---|---|
< | Less than | lt(a, b) | 3 < 1, 'a' < 'z' |
> | Greater than | gt(a, b) | 4 > 2, 'z' > 'a' |
== | Equals | eq(a, b) | 'a' == 'a' |
!= | Not equals | ne(a, b) | 1 ! = 2, 'Jim' != 'Jack' |
<= | Smaller equals | le(a, b) | 9 <= 10, 10 <= 10 |
>= | Greater equals | ge(a, b) | 11 >= 10, 10 >= 10 |
Logical operators
Python’s logical “and” and “or” operators link multiple operands following Boolean logic. As a result, both operators return the last evaluated object. Python’s logical “not” operator interprets an object in the Boolean context and negates its truth value:
Python operator | Meaning | Operator function | Example |
---|---|---|---|
and | Logical AND | no direct correspondence | True and False == False, 'name' and ... == ... |
or | Logical OR | no direct correspondence | False or True == True, a = '' or 'Default'; assert a == 'Default'. |
not | Denial | not_(a) | not True == False |
It is useful to visualize the effect of logical operations at truth tables. Below is the logical “AND”:
and | True | False |
True | True | False |
False | False | False |
And the logical “OR”:
or | True | False |
True | True | True |
False | True | False |
The operands of Python Boolean operators are by no means limited to Boolean variables. Any Python object can be interpreted in a Boolean context. The following objects evaluate to false in the Boolean context and are referred to as “falsy”:
Object | Explanation |
---|---|
False, None | Constants which are False according to the definition |
0, 0.0, Decimal(0), Fraction(0, 1), etc. | Number which represents zero |
'', (), [], {}, set(), range(0), etc. | Empty sequence or collection |
Bitwise operators
Python’s bitwise operators operate on integers, which are interpreted as bit sequences. They are all binary operators except for the bitwise “NOT” operator:
Python operator | Meaning | Operator function | Example |
<< | Shift bit sequence to the left | lshift(a, b) | 5 << 3 == 5 * 2 ** 3 |
>> | Shift bit sequence to the right | rshift(a, b) | 1 >> 1 == 0, 8 >> 1 == 4 |
& | Combine two bit sequences by “AND” | and_(a, b) | `` |
| | Concatenate two bit sequences by “OR” | or_(a, b) | `` |
^ | Linking two bit sequences using “XOR” | xor(a, b) | `` |
~ | Invert bit sequence with “NOT” | invert(a) | `` |
The bitwise operators are suitable for optimized mathematical operations. The left shift corresponds to a multiplication by a power of two:
Expression | 23 = 8 | 22 = 4 | 21 = 2 | 20 = 1 | Decimal |
b = 6 | 0 | 1 | 1 | 0 | 6 |
b << 1 | 1 | 1 | 0 | 0 | 12 |
b >> 1 | 0 | 0 | 1 | 1 | 3 |
We have constructed a table of the individual bits to illustrate the bitwise “AND”, “OR”, and “NOT” operations. The operations are applied to a number in binary representation using a bit mask:
Expression | 23 = 8 | 22 = 4 | 21 = 2 | 20 = 1 | Decimal |
bits = 6 | 0 | 1 | 1 | 0 | 6 |
mask = 5 | 0 | 1 | 0 | 1 | 5 |
bits & mask | 0 | 1 | 0 | 0 | 4 |
bits | mask | 0 | 1 | 1 | 1 | 7 |
bits ^ mask | 0 | 0 | 1 | 1 | 3 |
Python’s bitwise “NOT” operator inverts a bit sequence. This turns every 1 into a 0 and vice versa. Furthermore, the number’s sign is reversed:
Expression | 23 = 8 | 22 = 4 | 21 = 2 | 20 = 1 | Decimal |
b = 6 | 0 | 1 | 1 | 0 | 6 |
~ b | 1 | 0 | 0 | 1 | -7 |
Assignment Operators
Assignments are one of the basic statements in most programming languages. The Python assignment operators bind a value to a variable name. There is the newer “walrus” operator in addition to the assignment statement, which allows assignment within an expression. There are also several extended assignment statements which combine an assignment with another operation:
Python operator | Meaning | Operator function | Example |
---|---|---|---|
= | Assignment statement | no direct correspondence | name = 'Walter' |
:= | Assignment expression (“walrus” operator) | no direct correspondence | [ half for x in range(10) if (half := x / 2) < 5 ] |
+= | Advanced addition assignment | iadd(a, b) | x = 1; x += 4; assert x == 5 |
Python knows extended assignment operators for the arithmetic and bitwise operations. We do not list these individually here. We simply show the general pattern using the extended concatenation assignment as an example. A code which appends another part to an existing string is shown first:
name = 'Walter'
name = name + 'White'
assert name == 'WalterWhite'
An equivalent example using Python’s extended concatenation operator “+=” yields the same result is obtained, but the code is more concise and expressive:
name = 'Walter'
name += 'White'
assert name == 'WalterWhite'
Identity Operators
The Python is operator tests whether two variables refer to the same object in storage. Object identity contrasts with object equality, which is tested by the Python comparison operator “==”. The “is” in Python is similar to JavaScript’s strict equality operator “===”. Python also has a negated identity test with the “is not” operator:
Python operator | Meaning | Operator function | Example |
---|---|---|---|
is | Identity Test | is_(a, b) | a = 42; b = a; assert a is b |
is not | Negated Identity Test | is_not(a, b) | assert [42] is not [42] |
Let’s look at a few examples. We create a reference to an object in storage. We create another reference as an alias later. The is operator returns true when both variables point to the same object in storage:
# assign value to name
a = [42]
# reference existing object
b = a
# if this holds
assert a is b
# so will this
assert a == b
We create two references to independent objects in memory in the example below. Although the objects are the same, they are distinct. The is operator will return false in this case:
# assign the same value to different names
a = [42]
b = [42]
# `a`, `b` are two different objects
assert a is not b
# that contain the same value
assert a == b
Conditional operator
Python’s conditional operator can be used in place of the “if-else” keywords. The conditional operator is popularly used to distinguish between two possible values in assignments. It is also known as a ternary operator, as the conditional operator combines a condition and two expressions.
Python operator | Meaning | Operator function | Example |
---|---|---|---|
... if ... else ... | Conditional expression | no direct correspondence | name = 'Jim' if age == 42 else 'Jack' |
Let’s look at an example using the if-else statement in Python first. The following code sets Celsius or Fahrenheit as the unit for a temperature measurement depending on the chosen measurement system:
if system == 'metric':
unit = 'C'
else:
unit = 'F
The code can be simplified to a single assignment using the conditional operator:
unit = 'C' if system == 'metric' else 'F'.
Set operators
In addition to strings, tuples, lists, and dictionaries, Python supports sets as a composite data type by default. Overloaded operators are defined for the usual set operations:
Python operator | Meaning | Operator function | Example | ||
---|---|---|---|---|---|
& | Union of two sets | and_(a, b) | {'a', 'b'} & {'a', 'c'} == {'a'} | ||
Intersection of two sets | or_(a, b) | {'a', 'b'} | {'a', 'c'} == {'a', 'c', 'b'} | ||
^ | Form symmetrical difference of two sets | xor(a, b) | {'a', 'b'} ^ {'a', 'c'} == {'c', 'b'} | ||
- | Difference of two sets | sub(a, b) | {'a', 'b'} - {'a'} == {'b'} | ||
> | Tests if quantity is a true superset | gt(a, b) | assert {'a', 'b'} > {'a'} | ||
>= | Tests if a set is a superset | ge(a, b) | assert {'a'} >= {'a'} | ||
< | Tests if quantity is a true subset | lt(a, b) | assert {'a'} < {'a', 'b'} | ||
<= | Tests if quantity is a subset | le(a, b) | assert {'a'} <= {'a'} |
Membership Operators
The Python membership operators “in” and “not in” provide an indication of whether an object is included in a collection.
Python operator | Meaning | Operator function | Example |
---|---|---|---|
in | Tests whether an object is contained in an iterable | contains(a, b) | 'y' in 'Python' |
not in | Negation of the in operator | not contains(a, b) | 'x' not in 'Python' |
Membership operators work with iterables and use an equality check to determine if the target object is in the collection:
'Py' in 'Python'
'Px' not in 'Python'
'Jack' in ['Jim', 'Jack']
Using the “in” operator saves writing code of the following form:
def my_in(target, collection):
for element in collection:
if element == target:
return true
return False
# test
word = 'Python'
letter = 'y'
assert (my_in(letter, word)) == (letter in word)
Concatenation operator
The concatenation operator is used to concatenate sequences of the same type. The operator symbol is the plus sign.
Python operator | Meaning | Operator function | Example |
---|---|---|---|
+ | Links two sequences | add(a, b) | ['Jim'] + ['Jack', 'John'] |
Let’s look at a few examples. We concatenate two strings, two lists and two tuples:
assert "Walter" + "White" == 'WalterWhite'
assert ['a', 'b'] + ['c'] == ['a', 'b', 'c']
assert ('q', 'r') + ('s', 't') == ('q', 'r', 's', 't')
Python is used as an internet programming language. The concatenation operator can be used to assemble HTML tags:
site_title = 'Welcome'
print('<h1>' + site_title + '</h1>')
The concatenation operators differ in Python and PHP. This is because PHP uses the dot “.” as a symbol. The same example is shown below in PHP:
$siteTitle = 'Welcome';
echo '<h1>' . $siteTitle . '</h1>';
Index and slice operators
The Python index operator is used to extract a specific element of a collection. The slice operator is used to extract a subsequence.
Python operator | Meaning | Operator function | Example |
---|---|---|---|
iterable[index] | Returns the element of an iterable located under the index. | getitem(iterable, index) | 'Python'[1] == 'y' |
sequence[start:stop:step] | Returns a slice of a sequence | getitem(iterable, slice(start, stop, step)) | 'Python'[0:1] == 'Py', 'Python'[0:-1:2] == 'Pto' |
Python’s index and slice operators revert to Dunder’s __getitem__() method. This is enabled with either a numeric index or a slice object:
names = ['Jim', 'Jack', 'John']
names[0] == names.__getitem__(0)
names[0:2] == names.__getitem__(slice(0, 2))
The slice operator is handy because it allows a subsequence to be extracted without using a Python for-loop or Python while-loop. This saves programmers from writing code in the following form:
word = 'Python'
start, stop, step = 0, 5, 2
index, substring = start, ''
while index in range(start, stop, step):
substring += word[index]
index += step
# test
assert substring == word[start:stop:step]