## Operators

**Operators** are special tools used to perform various operations on data. Operators can be denoted with special characters (+, -, *…), or with short words (in, or…).

## Operator types (number of arguments)

Depending on how many arguments our operator needs for execution, we have **unary** (one argument) and **binary** (two arguments) operators.

```
>>> x = 5
>>> y = 10
>>> z = y/x #binary operator /
>>> print(z)
2
>>> -x #unary operator -
-5
```

## Operator types (operations they perform)

In Python, we have **arithmetic**, **relational**, **logical**, **bitwise**, **assignment**, **membership** and **identity** **operators**.

## Arithmetic operators

**Arithmetic operators**are the most common of them all and are used, as the name says, for arithmetic operations. When we use data values of different types,

**implicit conversion**is performed (the type is automatically transformed into the appropriate one for the given operation). However, if a conversion isn’t possible, program will signal an error. There are also operators that work only with numeric data types.

**addition**

**operator**(

**+**) – sums two data values; data types are not necessarily the same, hence implicit conversion is used; addition of strings is called concatenation

```
>>> 3 + 0.14
3.14
>>> 8 + True #True has an integer value of 1
9
>>> "abc" + "def"
'abcdef'
>>> "xyz" + 1
TypeError: can only concatenate str (not "int") to str
#str + int is not allowed
```

–**subtraction** **operator** ( **–** ) – subtracts the second data value from the first; works only with numeric data types

```
>>> 5 - 14
-9
>>> 6.9 - True
5.9
>>> "wipher" - "her"
TypeError: unsupported operand type(s) for -: 'str' and 'str'
```

–**multiplication** **operator** ( ***** ) – multiplies two data values. If both values are non-numerical, the program will signal an error. In contrast, multiplication of integer and string data values is allowed

```
>>> 15 * 3
75
>>> 4.5 * 3.9
17.55
>>> "abc" * "xyz"
TypeError: can't multiply sequence by non-int of type 'str'
>>> "abc" * 2
'abcabc'
```

–**division operator** ( **/** ) – divides first data value with the second one; works only with numeric data types

```
>>> 100 / 4
25
>>> 10 / 3
3.3333333333333335
>>> "aaaaaa" / 3
TypeError: unsupported operand type(s) for /: 'str' and 'int'
```

–**exponentiation operator** ( ****** ) – raises the first data value to the power of the second one. Works only with numeric data types

```
>>> 2 ** 3
8
>>> 121 ** 0.5
11
>>> 1000 ** 0.35
11.220184543019633
```

–**modulus operator** ( **%** ) – divides the first data value by the second one and returns their remainder. Works only with numeric data types

```
>>> 16 % 4
0
>>> 13 % 3
1
>>> 42 % 2.5 #divider doesn't have to be integer value
2.0
```

–**floor division operator** ( **//** ) – divides the first data value by the second one and then rounds the quotient to the first lower integer value. Works only with numeric data types

```
>>> 10 // 5
2
>>> 13 // 4
3
>>> 23 // 3.33
6.0
```

## Relational operators

**Relational operators**are used for comparison of two data values. Their result is a boolean value (True or False). They can be used with numeric types, as well as strings (in this case, we use string length for comparison), however some relational operators cannot be used between string and numeric type.

**greater than operator**(

**>**)

```
>>> 3.14 > 5
False
>>> "abcdef" > 5 #this is not supported
TypeError: '>' not supported between instances of 'str' and 'int'
```

–**less than operator** ( **< **)

```
>>> "xyz" < "pqrst" #we compare both strings' length
True
```

–**equal to operator** ( **==** )

```
>>> 12 == 35
False
>>> "apple" == 5 #this is ok
True
```

–**not equal to operator** ( **!= **)

```
>>> "tiger" != 8 #this is also ok
True
>>> "pig" != "cat"
False
```

–**greater then or equal to operator** ( **>=** )

```
>>> 13 >= 13
True
```

–**less than or equal to operator** ( **<= **)

```
>>> "wolf" <= "beer"
True
```

## Logical operators

**Logical operators**are used to perform logical operations between two data values. The values are viewed as boolean data type (True if value != 0, False if value == 0). Logical operators can be used with strings, in which case we use string lengths for calculations.

**logical and operator**(

**and**) – the expression “

**var1 and var2**” first evaluates

**var1**and, if it’s false (

**var1**== 0), returns

**var1**, otherwise result is

**var2**

```
>>> True and False
False
>>> 3 and 8
8
```

–**logical or operator** ( **or **) – the expression “**var1 or var2**” first evaluates **var1** and, if it’s false, returns **var2**, otherwise the result is **var1**

```
>>> 7 or 10
7
>>> "Predator" or "Alien"
'Predator'
```

–**logical not operator** ( **not **) – the expression “**not(var)**” returns True if **var** is false, else returns False

```
>>> not(12)
False
>>> not(0)
True
>>> not('')
True
```

## Bitwise operators

**Bitwise**operators are used for processing integer values, but in the process, binary representations of those values are used. Binary operators can only be used with integers.

**bitwise and**(

**&**) – logical and bit-by-bit

```
>>> 3 & 4 #011 & 100 = 000
0
>>> 7 & 12 #0111 & 1100 = 0100
4
```

–**bitwise or** (** |** ) – logical or bit-by-bit

```
>>> 3 | 12 #0011 | 1100 = 1111
15
```

–**bitwise xor** ( **^** ) – logical xor bit-by-bit (xor returns 0 if the bits have the same value, otherwise returns 1)

```
>>> 6 ^ 19 #10011 ^ 00110 = 10101
21
```

–**bitwise 1’s complement** ( **~** ) – for value “x”, it returns “-(x+1)”

```
>>> ~4
-5
>>> ~13
-14
```

–**bitwise left-shift** ( **<<** ) – shifts the bitwise representation of a value for a defined number of bits to the left. Each shifting to the left represents multiplication of our value by 2. Shifting by a negative number is not allowed (program signals an error)

```
>>> 11 << 1 #1011 shifted 1 bit to the left is 10110 (22 in decimal representation)
22
>>> 9 << 2 #1001 shifted 2 bits to the left is 100100 (36 in decimal representation)
36
```

–**bitwise right-shift **(** >>** ) – shifts the bitwise representation of a value for a defined number of bits to the right. Each shifting to the right represents floor division of our value by 2. Shifting by a negative number is not allowed (program signals an error)

```
>>> 16 >> 1 #10000 when shifted 1 bit to the right is 1000 (8 in decimal representation)
8
>>> 35 >> 3 #100011 when shifted 3 bits to the right is 100 (4 in decimal representation)
4
```

## Assignment operators

**Assignment operators**are used to assign a value to a variable. They are divided into two categories:

**assign operator****combined assignment operators**.

**Assign operator**(

**=**) is used to set a value of any data type to our variable.

`>>> a = "elephant"`

**Combined assignment operators** are a combination of an arithmetic/bitwise operator and the assign operator. These operators work as follows:

```
x @= y
Symbol @ represents the arithmetic or bitwise operator used in the combination with the assign operator
(=). Expression x @= y is equivalent to x = x @ y, but this way we saved up a little space in our code.
```

**add and assign operator**(

**+=**)

```
>>> b = 8
>>> b += 2
>>> print(b)
10
```

**-subtract and assign operator** ( **-=** )

```
>>> c = 5
>>> c -= 3
>>> print(c)
2
```

–**multiply and assign operator** ( ***=** )

```
>>> d = 5
>>> d *= 4
>>> print(d)
20
```

–**divide and assign operator** ( **/=** )

```
>>> e = 75
>>> e /= 5
>>> print(e)
15
```

–**exponentiation and assign operator** ( ****=** )

```
>>> f = 2
>>> f **= 10
>>> print(f)
1024
```

–**modulus and assign operator** ( **%=** )

```
>>> g = 13
>>> g %= 5
>>> print(g)
3
```

–**floor division and assign operator** ( **//=** )

```
>>> h = 125
>>> h //= 11
>>> print(h)
11
```

–**bitwise and and assign** ( **&=** )

```
>>> i = 3
>>> i &= 4
>>> print(i)
0
```

–**bitwise or and assign** ( **|=** )

```
>>> j = 12
>>> j |= 2
>>> print(j)
14
```

–**bitwise xor and assign** ( **^=** )

```
>>> k = 6
>>> k ^= 14
>>> print(k)
8
```

–**bitwise left shift and assign** ( **<<=** )

```
>>> l = 5
>>> l <<= 2
>>> print(l)
20
```

–**bitwise right shift and assign** ( **>>=** )

```
>>> m = 17
>>> m >>= 3
>>> print(m)
2
```

There can be only one assignment operator in the expression:

```
>>> x = 15
>>> y = (x += 2) #we cannot have two assignment operators
SyntaxError: invalid syntax
```

## Identity operators

**Identity operators**are used to determine whether a value is of a certain class(classes will be explained in later chapters) or type. The result value is a boolean (True or False). Identity operators can be used with any data type.

**is operator**(

**is**) – returns True if the data type or value on the left

**is**the same as the data type/value specified on the right, otherwise returns False

```
>>> x = 10
>>> type(x) is float
False
>>> type(x) is int
True
```

–**not is operator** ( **is not** ) – returns True if the type of the value on the left **is not** the same as the type specified on the right, otherwise returns False

```
>>> x = "pikachu"
>>> y = "hesoyam"
>>> z = 2.5
>>> type(x) is not type(y)
False
>>> type(x) is not type(z)
True
```

## Membership operators

**Membership operators**are used to check if a value belongs to a list or a tuple (more complex data types that will be explained in one of the next lessons).

**in operator**(

**in**) – returns True if the value is in the list or tuple, otherwise returns False

**not in operator**(

**not in**) – returns True if the value isn’t in the list or tuple, otherwise returns False

```
>>> arr = [1, 2, 3, 4, 5] #definition of a list
>>> var1 = 4
>>> var2 = 3.5
>>> var1 in arr #we check if var1 is element of arr
True
>>> var2 not in arr #we check if var2 is element of arr
True
```

## Operator precedence

**Operator precedence**is very important when facing this kind of problems. It shows us the order of operation execution in case we have to perform multiple operations in a single expression in our program. Also, we must keep in mind the

**associativity**– when we have multiple operators of the same level of priority one after another in an expression, we must know whether we execute them from

**left to right**, or

**from right to left**.

Here’s an example of how operator precedence works, as well as associativity among operators of the same priority level:

```
>>> x = 15
>>> y = 23
>>> z = 46
>>> res = -~(x + y | 4 ^ z // x) ** 2
1522
>>> '''order of operation execution:
1. parentheses
2. addition
3. floor division
4. bitwise XOR
5. bitwise OR,
6. exponentiation,
7. bitwise complement
8. unary minus
'''
```

## Table of contents

- Basic Data Structures
- Functions
- Collections
- Exceptions
- Input & Output
- RegEx & PRNG
- Classes And Objects
- Popular Libraries
- Additional Problems