# Operators Reference

Right from the start of the class, we will be dealing with operators in Python, which work somewhat like the same operators you're familiar with from math, although while their use in mathematical formulae indicates some kind of relationship between values, in Python, they correspond to simplification steps for the computer to carry out. Python also deals with more than just numbers, and the same operator can have different behavior depending on the types of its operands.

The table below includes very brief reference explanations for every operator that we'll use in this class, along with tiny examples of how they can be used correctly (feel free to paste those examples into your Python shell to see what the results are and double-check your understanding). This is meant as a quick reference guide, not a thorough explanation of all of the details.

# Reference

Operator Effect Example(s) Math Operators `+` Adds the left- and right-hand numbers together, resulting in a number, or concatenates the left- and right-hand strings, resulting in a string. Can also be used to concatenate lists or tuples. If either operand is a floating point number, the result will be a floating-point number, but if they're both integers the result will be an integer. `1 + 2.5` `"abc" + "def"` `-` Subtracts the right-hand number from the left-hand number, resulting in a number. Like `+`, the type of the result (`int` or `float`) depends on the types of the operands. `-` Can also be used as a unary operator to construct a negative value. Note that `-` is much less flexible than `+` as it cannot be used with strings or other sequences. `2 - 1` `-4.5` `*` Multiplies the left- and right-hand numbers together, or creates a longer string by repeating the left-hand string the right-hand integer number of times. When used with a string, the right-hand value must be an integer. `3 * 4` `'ha' * 3` `/` Divides the left-hand number by the right-hand number. The result will always be a floating-point number, even if the two numbers divide evenly. Attempting to divide by 0 causes a `ZeroDivisionError`. `12 / 3` `0.5/0.2` `//` Divides the left-hand number by the right-hand number, and then rounds towards negative infinity to produce an integer result. Attempting to divide by zero is still an error. `12 // 3` `999 // 1000` `-12 // 5` `%` Computes the modulus of the left-hand number by the right-hand number. For positive numbers, this is the same as the remainder after division. For negative numbers, it's different. The modulus will always have the same sign as the right-hand number, unless the result is 0 (which it is for all multiples of the right-hand number). `5 % 3` `-4 % 5` `-4 % -5` `**` Raises the left-hand number to the right-hand exponent. Result is a floating-point number if either operand is one, but is an integer if both operands are integers. `3 ** 2` `3 ** 0.0` `5 ** -1` Comparators Note Two comparators can be chained together and the result will be `True` only if both comparisons succeed. For example `1 <= x < 5` will be true if the value of the variable `x` is greater than or equal to 1 and also strictly less than 5. `==` Read as 'equals', this comparator results in `True` when its left- and right-hand sides are the same as each other. Note that with floating-point numbers, two numbers that should be the same may exhibit different rounding errors. `1 == 1` `"abc" == 'abc'` `1.0 == 1` `(5 * 1.0) / 2.54 == 5 * (1.0 / 2.54)` `!=` Read as 'not equals', this comparator results in `True` when its left- and right-hand sides are not the same as each other. Any kind of values may be compared. `1 != 3` `'abc' != 123` `1.4 != 1.4` `<` / `<=` `True` when the left-hand number is smaller than the right-hand number, or when the left-hand sequence (e.g., string or list) would come before the right-hand sequence in sorted order (i.e., dictionary order for strings). The `<=` form is additionally `True` when `==` would be `True`. `0 < 1` `'aardvark' < 'aardvarl'` `>` / `>=` The inverses of `<` and `<=` these are `True` when their left-hand value is greater than their right-hand value, either numerically or based on ordering. `>=` is also true when the two sides are the same (based on `==`). `15 > -15` `[3, 1] > [2, 10]` `is` / `is not` `True` when the objects on the left and right hand side are the same object, whether or not they have the same structure (which `==` can check). Use this to distinguish between aliasing and cloning situations. Should usually only be used with `None` and with mutable types like lists and dictionaries, since results are interesting for immutable types like numbers and strings. The `is not` form just returns the opposite result. `x is None` ` Logical Operators Note Logical operators treat their operands as boolean values even when they aren't. For numbers, any value other than 0 is treated as `True`, and exactly 0 is treated as `False`. For strings and other sequences, any non-empty sequence is treated as `True`, and any empty sequence is treated as `False`. We call these other values "truthy" or "falsey" respectively, although it's generally better to use a comparison operator or predicate to create a real boolean value yourself. The `bool` function can be used to explicitly convert a value to a boolean, e.g., `bool(4)`. `and` `True` if both the left- and right-hand values are truthy. `and` happens **after** `or`, just like `+` happens after `*`. When used with non-boolean values, the result is actually the right-hand value if both are truthy, or the first value that isn't truthy if one of them isn't, but relying on this behavior is bad style. `True and True` `x > 3 and x % 2 == 0` `or` `True` if either the left- or right-hand values are truthy. `or` happens **before** `and`, just like `*` happens before `+`. When used with non-boolean values, the result is actually the left-hand value if it is truthy, or the right-hand value if the left-hand value isn't truthy (regardless of whether or not the right-hand value is truthy), but relying on this behavior is bad style. `False or True` `x < 'd' or x > 's'` `w and (x or y) and z` `not` Reverses a boolean value, turning `True` into `False` and vice versa. For non-boolean values, the value is first converted to a boolean and the reversed, so the result is always a boolean. Applies **before** both `and` and `or`, just like a `-` sign for a negative number applies before `+` and `*`. `not (1 <= x <= 3)` `not False or True` `not (False or True)` Special Operators `in` / `not in` Checks whether the left-hand operator is part of the right-hand sequence. If they are both strings, this will be `True` if the left-hand string can be found as a contiguous sub-string of the right-hand string. If the right-hand-side is a list, it will be `True` if the left-hand-side value is `==` to one of the elements of that list. If the right-hand side is a dictionary, it will be `True` if the left-hand is `==` to one of the keys of the dictionary (values are ignored). The `not in` variant just returns the opposite result. `'ab' in 'abc'` `'ab' in 'acb'` `'ab' in ['a', 'b', 'c']` `[1, 2] in [[1, 2], [3, 4]]` `.` This is not really an operator, but it's used followed by a name to retrieve an associated or bound value, often a function. For example, after importing a module, use `.` to extract and use functions or values from that module. Or use it to refer to build-in methods of common types like strings. ``import mathmath.sin(math.pi)`` `'a-b-c'.split('-')` `'-'.join(['a', 'b', 'c'])` `[]` Not really an operator, but used to access an individual item from a collection (this is called "subscripting"). For lists, tuples, and strings, the value inside the brackets must be an integer, and it will be used as an index to pull out a single item from the sequence. For dictionaries, the value inside the brackets must be a key, and the result will be the associated value. In both cases, an invalid index (e.g., past the end of the sequence) or key (e.g., a key that's not in the dictionary) will result in an error. For sequences, zero is the first element, and negative indices count backwards from the end. `'abc'` `'last'[-1]` ``nums = [1, 2, 3]x = nums`` ``d = {1: 2, 3: 4}x = d`` `[:]` When square brackets have a colon inside, the result is a slice instead of a subscript. Slices are used to pull out multiple items from a sequence, so the result will be a sequence of the same type as the sequence that was sliced. There can be one or two colons, and thus two or three values specified, but missing values will be filled with defaults. The first value specifies the start of the slice, the second specifies the end, and the third (if present) specifies the step value. The resulting sequence will start within the base sequence at the given start index (default is the beginning of the sequence), include all items whose indices are that index plus multiples of the step value (default is 1 meaning every item), and it will stop before the given end index (default is the end of the sequence). With a negative step value, the order will be reversed, and the start index must be after the end index (in this case, the default start and end are swapped). Slicing only works with ordered sequences (e.g., strings, lists, and tuples), not with dictionaries or sets. `'abcd'[1:3]` `'abcd'[::2]` `'abcd'[::-1]`