# 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:

```none
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:

```none
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:

<table>
  <tbody>
    <tr>
      <td><strong>Classes of Python operators</strong></td>
      <td><strong>Explanation</strong></td>
      <td><strong>Operands</strong></td>
      <td><strong>Result</strong></td>
      <td><strong>Operators at a glance</strong></td>
    </tr>
    <tr>
      <td>Arithmetic operators</td>
      <td>Combine two numbers to form a new number</td>
      <td>Numbers</td>
      <td>Number</td>
      <td>+, -, \*, /, //, %, \*\*, @</td>
    </tr>
    <tr>
      <td>Comparison operators</td>
      <td>Compare two expressions with each other</td>
      <td>Expressions</td>
      <td>Boolean</td>
      <td>&lt;, &gt;, ==, !=, &lt;=, &gt;=</td>
    </tr>
    <tr>
      <td>Logical operators</td>
      <td>Combine expressions in a Boolean context</td>
      <td>Expressions</td>
      <td>Last evaluated expression / Boolean</td>
      <td>and, or, not</td>
    </tr>
    <tr>
      <td>Bitwise operators</td>
      <td>Manipulate integers as binary sequences</td>
      <td>Numbers</td>
      <td>Number</td>
      <td>&lt;&lt;, &gt;&gt;, &amp;, |, ^, ~</td>
    </tr>
    <tr>
      <td>Assignment operators</td>
      <td>Assign value to a name</td>
      <td>Lvalue, Rvalue</td>
      <td>- / Evaluated expression</td>
      <td>=, :=, +=, -=, \*=, etc.</td>
    </tr>
    <tr>
      <td>Identity operators</td>
      <td>Determine whether two names refer to the same object</td>
      <td>Objects</td>
      <td>Boolean</td>
      <td>is, is not</td>
    </tr>
    <tr>
      <td>Conditional operator</td>
      <td>Returns one of two values depending on a condition</td>
      <td>Expression, condition, alternative</td>
      <td>Expression / Alternative</td>
      <td>... if ... else ...</td>
    </tr>
    <tr>
      <td>Set operators</td>
      <td>Link two sets / Compare sets</td>
      <td>Quantities</td>
      <td>Quantity / Boolean</td>
      <td>&amp;, |, ^, -, &lt;, &gt;, &lt;=, &gt;=</td>
    </tr>
    <tr>
      <td>Membership operators</td>
      <td>Testing whether an iterable contains a specific object</td>
      <td>Object, Iterable</td>
      <td>Boolean</td>
      <td>in, not in</td>
    </tr>
    <tr>
      <td>Concatenation operator</td>
      <td>Chained sequences</td>
      <td>Strings / Lists / Tuples</td>
      <td>String / List / Tuple</td>
      <td>+</td>
    </tr>
    <tr>
      <td>Index and slice operators</td>
      <td>Return one or more elements of an iterable</td>
      <td>Iterable, Index / Slice</td>
      <td>String / List / Tuple</td>
      <td>\[\], \[::\]</td>
    </tr>
  </tbody>
</table>

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:

<table>
  <thead>
    <tr>
      <th>Operator arity</th>
      <th>Number of operands</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Unary</td>
      <td>One operand</td>
      <td>not single\_value</td>
    </tr>
    <tr>
      <td>Binary</td>
      <td>Two operands</td>
      <td>left\_operand + right\_operand</td>
    </tr>
    <tr>
      <td>Ternary</td>
      <td>Three operands</td>
      <td>some\_value if condition else other\_value</td>
    </tr>
  </tbody>
</table>

### 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”:

```none
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:

```none
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:

```none
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:

```none
8 + 3 == 11
```

We concatenate **two strings** using the same operator:

```none
"Walter" + "White" == "WalterWhite"
```

We also concatenate **lists** with the plus operator:

```none
['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](https://docs.python.org/3/library/operator.html "operator - Standard operators as functions - Python 3.10.4 documentation") 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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Operator function</th>
      <th>Dunder method</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a + b</td>
      <td>operator.add(a, b)</td>
      <td>a.\_\_add\_\_(b)</td>
    </tr>
  </tbody>
</table>

Operators use the **infix notation** which inserts the operator between the operands, while the functional style uses the prefix notation. Both notations are equivalent:

<table>
  <thead>
    <tr>
      <th>Notation</th>
      <th>Use</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Infix</td>
      <td>Operators</td>
      <td>a + b</td>
    </tr>
    <tr>
      <td>Prefix</td>
      <td>Functions</td>
      <td>+ a b / add(a, b)</td>
    </tr>
  </tbody>
</table>

Let’s consider an example. We **define two numbers and add them** to the operator, the operator function and the corresponding Dunder method:

```none
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:

```none
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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>+</td>
      <td>Addition / unary plus</td>
      <td>add(a, b) / pos(a)</td>
      <td>5 + 3 == 8 / +8 == 4 + 4</td>
    </tr>
    <tr>
      <td>-</td>
      <td>Subtraction / unary minus</td>
      <td>sub(a, b) / neg(a)</td>
      <td>7 - 2 == 5 / -4 == 2 - 6</td>
    </tr>
    <tr>
      <td>\*</td>
      <td>Multiplication</td>
      <td>mul(a, b)</td>
      <td>2 \* 3 == 6</td>
    </tr>
    <tr>
      <td>/</td>
      <td>“Real” Division</td>
      <td>truediv(a, b)</td>
      <td>8 / 2 == 4.0, 7 / 2 == 3.5</td>
    </tr>
    <tr>
      <td>//</td>
      <td>Integer division to next lower integer</td>
      <td>floordiv(a, b)</td>
      <td>8 // 2 == 4, 7 // 2 == 3</td>
    </tr>
    <tr>
      <td>%</td>
      <td>Modulus: Integer division’s remaining amount</td>
      <td>mod(a, b)</td>
      <td>8 % 2 == 0, 7 % 2 == 1</td>
    </tr>
    <tr>
      <td>\*\*</td>
      <td>Exponentiation</td>
      <td>pow(a, b)</td>
      <td>2 \*\* 3 == 8, 10 \*\* -1 == 0.1</td>
    </tr>
    <tr>
      <td>@</td>
      <td>Matrix multiplication</td>
      <td>matmul(a, b)</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

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:

```none
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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&lt;</td>
      <td>Less than</td>
      <td>lt(a, b)</td>
      <td>3 &lt; 1, 'a' &lt; 'z'</td>
    </tr>
    <tr>
      <td>&gt;</td>
      <td>Greater than</td>
      <td>gt(a, b)</td>
      <td>4 &gt; 2, 'z' &gt; 'a'</td>
    </tr>
    <tr>
      <td>==</td>
      <td>Equals</td>
      <td>eq(a, b)</td>
      <td>'a' == 'a'</td>
    </tr>
    <tr>
      <td>!=</td>
      <td>Not equals</td>
      <td>ne(a, b)</td>
      <td>1 ! = 2, 'Jim' != 'Jack'</td>
    </tr>
    <tr>
      <td>&lt;=</td>
      <td>Smaller equals</td>
      <td>le(a, b)</td>
      <td>9 &lt;= 10, 10 &lt;= 10</td>
    </tr>
    <tr>
      <td>&gt;=</td>
      <td>Greater equals</td>
      <td>ge(a, b)</td>
      <td>11 &gt;= 10, 10 &gt;= 10</td>
    </tr>
  </tbody>
</table>

### 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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>and</td>
      <td>Logical AND</td>
      <td>no direct correspondence</td>
      <td>True and False == False, 'name' and ... == ...</td>
    </tr>
    <tr>
      <td>or</td>
      <td>Logical OR</td>
      <td>no direct correspondence</td>
      <td>False or True == True, a = '' or 'Default'; assert a == 'Default'.</td>
    </tr>
    <tr>
      <td>not</td>
      <td>Denial</td>
      <td>not\_(a)</td>
      <td>not True == False</td>
    </tr>
  </tbody>
</table>

It is useful to visualize the **effect of logical operations** at truth tables. Below is the logical “AND”:

<table>
  <tbody>
    <tr>
      <td><strong>and</strong></td>
      <td><strong>True</strong></td>
      <td><strong>False</strong></td>
    </tr>
    <tr>
      <td>True</td>
      <td>True</td>
      <td>False</td>
    </tr>
    <tr>
      <td>False</td>
      <td>False</td>
      <td>False</td>
    </tr>
  </tbody>
</table>

And the logical “OR”:

<table>
  <tbody>
    <tr>
      <td><strong>or</strong></td>
      <td><strong>True</strong></td>
      <td><strong>False</strong></td>
    </tr>
    <tr>
      <td>True</td>
      <td>True</td>
      <td>True</td>
    </tr>
    <tr>
      <td>False</td>
      <td>True</td>
      <td>False</td>
    </tr>
  </tbody>
</table>

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”:

<table>
  <thead>
    <tr>
      <th>Object</th>
      <th>Explanation</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>False, None</td>
      <td>Constants which are False according to the definition</td>
    </tr>
    <tr>
      <td>0, 0.0, Decimal(0), Fraction(0, 1), etc.</td>
      <td>Number which represents zero</td>
    </tr>
    <tr>
      <td>'', (), \[\], {}, set(), range(0), etc.</td>
      <td>Empty sequence or collection</td>
    </tr>
  </tbody>
</table>

### 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:

<table>
  <tbody>
    <tr>
      <td><strong>Python operator</strong></td>
      <td><strong>Meaning</strong></td>
      <td><strong>Operator function</strong></td>
      <td><strong>Example</strong></td>
    </tr>
    <tr>
      <td>&lt;&lt;</td>
      <td>Shift bit sequence to the left</td>
      <td>lshift(a, b)</td>
      <td>5 &lt;&lt; 3 == 5 \* 2 \*\* 3</td>
    </tr>
    <tr>
      <td>&gt;&gt;</td>
      <td>Shift bit sequence to the right</td>
      <td>rshift(a, b)</td>
      <td>1 &gt;&gt; 1 == 0, 8 &gt;&gt; 1 == 4</td>
    </tr>
    <tr>
      <td>&amp;</td>
      <td>Combine two bit sequences by “AND”</td>
      <td>and\_(a, b)</td>
      <td>``</td> </tr> <tr> <td>|</td> <td>Concatenate two bit sequences by “OR”</td> <td>or\_(a, b)</td> <td>``</td> </tr> <tr> <td>^</td> <td>Linking two bit sequences using “XOR”</td> <td>xor(a, b)</td> <td>``</td> </tr> <tr> <td>~</td> <td>Invert bit sequence with “NOT”</td> <td>invert(a)</td> <td>``</td>
    </tr>
  </tbody>
</table>

The bitwise operators are **suitable for optimized mathematical operations**. The left shift corresponds to a multiplication by a power of two:

<table>
  <tbody>
    <tr>
      <td><strong>Expression</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimal</strong></td>
    </tr>
    <tr>
      <td>b = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>b &lt;&lt; 1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>12</td>
    </tr>
    <tr>
      <td>b &gt;&gt; 1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

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:

<table>
  <tbody>
    <tr>
      <td><strong>Expression</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimal</strong></td>
    </tr>
    <tr>
      <td>bits = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>mask = 5</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>5</td>
    </tr>
    <tr>
      <td>bits &amp; mask</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>4</td>
    </tr>
    <tr>
      <td>bits | mask</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>7</td>
    </tr>
    <tr>
      <td>bits ^ mask</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

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:

<table>
  <tbody>
    <tr>
      <td><strong>Expression</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimal</strong></td>
    </tr>
    <tr>
      <td>b = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>~ b</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>-7</td>
    </tr>
  </tbody>
</table>

### 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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>=</td>
      <td>Assignment statement</td>
      <td>no direct correspondence</td>
      <td>name = 'Walter'</td>
    </tr>
    <tr>
      <td>:=</td>
      <td>Assignment expression (“walrus” operator)</td>
      <td>no direct correspondence</td>
      <td>\[ half for x in range(10) if (half := x / 2) &lt; 5 \]</td>
    </tr>
    <tr>
      <td>+=</td>
      <td>Advanced addition assignment</td>
      <td>iadd(a, b)</td>
      <td>x = 1; x += 4; assert x == 5</td>
    </tr>
  </tbody>
</table>

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:

```none
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:

```none
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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>is</td>
      <td>Identity Test</td>
      <td>is\_(a, b)</td>
      <td>a = 42; b = a; assert a is b</td>
    </tr>
    <tr>
      <td>is not</td>
      <td>Negated Identity Test</td>
      <td>is\_not(a, b)</td>
      <td>assert \[42\] is not \[42\]</td>
    </tr>
  </tbody>
</table>

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**:

```none
# 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:

```none
# 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.

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>... if ... else ...</td>
      <td>Conditional expression</td>
      <td>no direct correspondence</td>
      <td>name = 'Jim' if age == 42 else 'Jack'</td>
    </tr>
  </tbody>
</table>

Let’s look at an example using the [if-else statement in Python](https://www.ionos.com/digitalguide/websites/web-development/python-if-else/) first. The following code sets Celsius or Fahrenheit as the **unit for a temperature measurement** depending on the chosen measurement system:

```none
if system == 'metric':
    unit = 'C'
else:
    unit = 'F
```

The code can be simplified to a single assignment **using the conditional operator**:

```none
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:

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&amp;</td>
      <td>Union of two sets</td>
      <td>and\_(a, b)</td>
      <td>{'a', 'b'} &amp; {'a', 'c'} == {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td></td>
      <td></td>
      <td>Intersection of two sets</td>
      <td>or\_(a, b)</td>
      <td>{'a', 'b'}</td>
      <td>{'a', 'c'} == {'a', 'c', 'b'}</td>
    </tr>
    <tr>
      <td>^</td>
      <td>Form symmetrical difference of two sets</td>
      <td>xor(a, b)</td>
      <td>{'a', 'b'} ^ {'a', 'c'} == {'c', 'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>-</td>
      <td>Difference of two sets</td>
      <td>sub(a, b)</td>
      <td>{'a', 'b'} - {'a'} == {'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&gt;</td>
      <td>Tests if quantity is a true superset</td>
      <td>gt(a, b)</td>
      <td>assert {'a', 'b'} &gt; {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&gt;=</td>
      <td>Tests if a set is a superset</td>
      <td>ge(a, b)</td>
      <td>assert {'a'} &gt;= {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&lt;</td>
      <td>Tests if quantity is a true subset</td>
      <td>lt(a, b)</td>
      <td>assert {'a'} &lt; {'a', 'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&lt;=</td>
      <td>Tests if quantity is a subset</td>
      <td>le(a, b)</td>
      <td>assert {'a'} &lt;= {'a'}</td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>

### Membership Operators

The Python membership operators “in” and “not in” provide an indication of whether an **object is** **included in a collection**.

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>in</td>
      <td>Tests whether an object is contained in an iterable</td>
      <td>contains(a, b)</td>
      <td>'y' in 'Python'</td>
    </tr>
    <tr>
      <td>not in</td>
      <td>Negation of the in operator</td>
      <td>not contains(a, b)</td>
      <td>'x' not in 'Python'</td>
    </tr>
  </tbody>
</table>

Membership operators work with **iterables** and use an **equality check** to determine if the target object is in the collection:

```none
'Py' in 'Python'
'Px' not in 'Python'
'Jack' in ['Jim', 'Jack']
```

Using the “in” operator saves writing code of the following form:

```none
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.

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>+</td>
      <td>Links two sequences</td>
      <td>add(a, b)</td>
      <td>\['Jim'\] + \['Jack', 'John'\]</td>
    </tr>
  </tbody>
</table>

Let’s look at a few examples. We concatenate **two strings, two lists and two tuples**:

```none
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](https://www.ionos.com/digitalguide/websites/web-development/web-programming-languages/ "Web programming languages"). The concatenation operator can be used to assemble [HTML tags](https://www.ionos.com/digitalguide/websites/web-development/html-tags/):

```none
site_title = 'Welcome'
print('<h1>' + site_title + '</h1>')
```

The concatenation operators differ in [Python and PHP](https://www.ionos.com/digitalguide/websites/web-development/php-vs-python/ "PHP vs. Python"). This is because PHP uses the dot “.” as a symbol. The same example is shown below in **PHP**:

```none
$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.

<table>
  <thead>
    <tr>
      <th>Python operator</th>
      <th>Meaning</th>
      <th>Operator function</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>iterable\[index\]</td>
      <td>Returns the element of an iterable located under the index.</td>
      <td>getitem(iterable, index)</td>
      <td>'Python'\[1\] == 'y'</td>
    </tr>
    <tr>
      <td>sequence\[start:stop:step\]</td>
      <td>Returns a slice of a sequence</td>
      <td>getitem(iterable, slice(start, stop, step))</td>
      <td>'Python'\[0:1\] == 'Py', 'Python'\[0:-1:2\] == 'Pto'</td>
    </tr>
  </tbody>
</table>

Python’s index and slice operators revert to Dunder’s *\_\_getitem\_\_()* method. This is enabled with either a numeric index or a slice object:

```none
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](https://www.ionos.com/digitalguide/websites/web-development/python-for-loop/) or [Python while-loop](https://www.ionos.com/digitalguide/websites/web-development/python-while-loop/). This saves programmers from writing code in the following form:

```none
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]
```


This is a markdown version of: [https://www.ionos.com/digitalguide/websites/web-development/python-operators/](https://www.ionos.com/digitalguide/websites/web-development/python-operators/) for AI/LLM consumption.