Binary Arithmetic Operations
Binary arithmetic operations have the conventional levels of precedence. Some of these operations also apply to certain non-numeric types. Aside from the exponentiation operator, there are two levels: one for multiplicative operators and another for additive ones:

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
            m_expr "//" u_expr | m_expr "/" u_expr |
            m_expr "%" u_expr
a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr
The * (multiplication) operator produces the product of its arguments. The arguments can both be numbers, or one argument must be an integer and the other a sequence. In the first case, the numbers are converted to a common type and then multiplied. In the second case, sequence repetition occurs; a negative repetition factor produces an empty sequence.

The @ (matrix multiplication) operator is intended for matrix multiplication. No built-in type in Python implements this operator.

The / (division) and // (floor division) operators produce the quotient of their arguments. Numeric arguments are converted to a common type. Division between integers produces a floating-point number, while floor division between integers results in an integer; the result is that of a mathematical division with the “floor” function applied to the result. Division by zero raises a ZeroDivisionError.

The % (modulus) operator produces the remainder of the division of the first argument by the second. Numeric arguments are converted to a common type. A zero argument on the right raises a ZeroDivisionError. Arguments can be floating-point numbers, e.g., 3.14 % 0.7 is equal to 0.34 (since 3.14 is equal to 4 * 0.7 + 0.34). The modulus operator always produces a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.

The floor division and modulus operators are connected by the following identity: x == (x // y) * y + (x % y). Floor division and modulus are also connected by the built-in function divmod(): divmod(x, y) == (x // y, x % y).

In addition to performing the modulus operation on numbers, the % operator is also overloaded by string objects for old-style string formatting (also known as interpolation). The syntax for string formatting is described in the Python Library Reference, section Old-Style String Formatting.

The floor division operator, the modulus operator, and the divmod() function are not defined for complex numbers. Instead, convert to a floating-point number using the abs() function if appropriate.

The + (addition) operator produces the sum of its arguments. The arguments must both be numbers or both be sequences of the same type. In the first case, the numbers are converted to a common type and then added. In the second case, the sequences are concatenated.

The - (subtraction) operator produces the difference between its arguments. Numeric arguments are converted to a common type.

Shift Operations
Shift operations have lower precedence than arithmetic operations:

shift_expr ::=  a_expr | shift_expr ("<<" | ">>") a_expr
These operators accept integers as arguments. They shift the first argument left or right by the number of bits specified by the second argument.

A right shift by n bits is defined as an integer floor division by pow(2, n). A left shift by n bits is defined as a multiplication by pow(2, n).

Binary Bitwise Operations
Each of the three binary bitwise operations has a different level of precedence:

and_expr ::= shift_expr | and_expr "&" shift_expr
xor_expr ::= and_expr | xor_expr "^" and_expr
or_expr ::= xor_expr | or_expr "|" xor_expr
* The & operator produces the bitwise AND of its arguments, which must be integers.

* The ^ operator produces the bitwise XOR (exclusive OR) of its arguments, which must be integers.

* The | operator produces the bitwise OR (inclusive OR) of its arguments, which must be integers.

Comparisons
Unlike C, all comparison operations in Python have the same priority, which is lower than any arithmetic, shift, or bitwise operation. Also, unlike C, expressions like a < b < c have the conventional mathematical interpretation:

comparison    ::=  or_expr (comp_operator or_expr)*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"
Comparisons produce boolean values: True or False.

Comparisons can be arbitrarily chained, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once.

Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

Note that a op1 b op2 c does not imply any comparison between a and c, so, for example, x < y > z is perfectly legal.

Value Comparisons
The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects do not need to be of the same type.

The chapter Objects, Values, and Types states that objects have a value (in addition to type and identity). The value of an object is a rather abstract notion in Python: For example, there is no canonical method to access the value of an object. Furthermore, there is no requirement that the value of an object must be constructed in a particular way, e.g., composed of all its data attributes. Comparison operators implement a particular notion of what an object's value is.

The default behavior for equality comparison (== and !=) is based on object identity. Therefore, comparison of instances with the same identity results in equality, and comparison of equality of instances with different identities results in inequality.

No default comparison order (<, >, <=, >=) is provided; an attempt generates a TypeError.

The following list describes the comparison behavior of the most important built-in types:

Numbers: Built-in numeric types (int, float, complex) and types from the standard library (fractions.Fraction and decimal.Decimal) can be compared with themselves and among their types, with the restriction that complex numbers do not support order comparisons. Within the limits of the involved types, they are compared mathematically correctly without loss of precision.
None and NotImplemented: They are singletons. PEP 8 advises that comparisons for singletons should be done with is or is not, never with equality operators.
Binary Sequences: Instances of bytes or bytearray compare lexicographically using the numeric values of their elements.
Character Strings: Instances of str compare lexicographically using Unicode code points (the result of the built-in ord() function) or their characters.
Sequences: Instances of tuple, list, or range can only be compared within their types, with the restriction that ranges do not support order comparisons. Equality comparisons between these types result in inequality, and order comparisons between these types generate TypeError. They compare lexicographically using comparison of their corresponding elements.
Mappings: Instances of dict compare equal if and only if they have the same (key, value) pairs.
Sets: Instances of set or frozenset can be compared with each other and among their types. They define order comparison operators with the intention of checking subsets and supersets.
Other Built-in Types: Most other built-in types do not have comparison methods implemented, so they inherit the default comparison behavior.
User-defined classes that customize their comparison behavior should follow some consistency rules, if possible:

Equality comparison should be reflexive.
Comparison should be symmetric.
Comparison should be transitive.
If any of these conditions are not met, the resulting behavior is undefined.