Learning Python - Mark Lutz [79]
Since this book addresses both Python 2.6 and 3.0, here are some notes about version differences and recent additions related to the operators in Table 5-2:
In Python 2.6, value inequality can be written as either X != Y or X <> Y. In Python 3.0, the latter of these options is removed because it is redundant. In either version, best practice is to use X != Y for all value inequality tests.
In Python 2.6, a backquotes expression `X` works the same as repr(X) and converts objects to display strings. Due to its obscurity, this expression is removed in Python 3.0; use the more readable str and repr built-in functions, described in Numeric Display Formats.
The X // Y floor division expression always truncates fractional remainders in both Python 2.6 and 3.0. The X / Y expression performs true division in 3.0 (retaining remainders) and classic division in 2.6 (truncating for integers). See Division: Classic, Floor, and True.
The syntax [...] is used for both list literals and list comprehension expressions. The latter of these performs an implied loop and collects expression results in a new list. See Chapters 4, 14, and 20 for examples.
The syntax (...) is used for tuples and expressions, as well as generator expressions—a form of list comprehension that produces results on demand, instead of building a result list. See Chapters 4 and 20 for examples. The parentheses may sometimes be omitted in all three constructs.
The syntax {...} is used for dictionary literals, and in Python 3.0 for set literals and both dictionary and set comprehensions. See the set coverage in this chapter and Chapters 4, 8, 14, and 20 for examples.
The yield and ternary if/else selection expressions are available in Python 2.5 and later. The former returns send(...) arguments in generators; the latter is shorthand for a multiline if statement. yield requires parentheses if not alone on the right side of an assignment statement.
Comparison operators may be chained: X < Y < Z produces the same result as X < Y and Y < Z. See Comparisons: Normal and Chained for details.
In recent Pythons, the slice expression X[I:J:K] is equivalent to indexing with a slice object: X[slice(I, J, K)].
In Python 2.X, magnitude comparisons of mixed types—converting numbers to a common type, and ordering other mixed types according to the type name—are allowed. In Python 3.0, nonnumeric mixed-type magnitude comparisons are not allowed and raise exceptions; this includes sorts by proxy.
Magnitude comparisons for dictionaries are also no longer supported in Python 3.0 (though equality tests are); comparing sorted(dict.items()) is one possible replacement.
We’ll see most of the operators in Table 5-2 in action later; first, though, we need to take a quick look at the ways these operators may be combined in expressions.
Mixed operators follow operator precedence
As in most languages, in Python, more complex expressions are coded by stringing together the operator expressions in Table 5-2. For instance, the sum of two multiplications might be written as a mix of variables and operators:
A * B + C * D
So, how does Python know which operation to perform first? The answer to this question lies in operator precedence. When you write an expression with more than one operator, Python groups its parts according to what are called precedence rules, and this grouping determines the order in which the expression’s parts are computed. Table 5-2 is ordered by operator precedence:
Operators lower in the table have higher precedence, and so bind more tightly in mixed expressions.
Operators in the same row in Table 5-2 generally group from left to right when combined (except for exponentiation, which groups right to left, and comparisons, which chain left to right).
For example, if you write X + Y * Z, Python evaluates the multiplication first (Y * Z), then adds that result to X because * has higher precedence (is lower in the table) than +. Similarly, in this section’s original example, both multiplications (A * B and C * D) will happen before