We'll look at the basic comparison operators. We'll also look at the
partial evaluation rules of the logic operators to show how we can build
more useful expressions. Finally, we'll look at floating-point equality
tests, which are sometimes done incorrectly.
We compare values with the comparison operators. These correspond
to the mathematical functions of <, ≤, >, ≥, = and ≠. Conditional
expressions are often built using the Python comparison operators: <,
<=, >, >=, == and != for less than, less than or equal to,
greater than, greater than or equal to, equal to and not equal
p1 < p2
p1 >= p2
When applying a comparison operator, we see a number of
Evaluate both argument values.
Apply the comparison to create a boolean result.
Convert both parameters to the same type. Numbers are
converted to progressively longer types: plain integer to long
integer to float to complex.
Do the comparison.
Return True or False.
We call out these three steps explicitly because there are some
subtleties in comparison among unlike types of data; we'll come to this
later when we cover sequences, mappings and classes in Part II, “Data Structures”. Generally, it doesn't make sense to compare unlike
types of data. After all, you can't ask "Which is larger, the Empire
State Building or the color green?"
Comparisons can be combined in Python, unlike most other
programming languages. We can ask:
0 <= a < 6 which
has the usual mathematical meaning. We're not forced to use the longer
0 <= a and a < 6 .
3 < p1 < 3.2
3 < p1 and p1 < 3.2
This is useful when
a is actually some complex
expression that we'd rather not repeat.
Also note that the preceding example had a mixture of integers and
floating-point numbers. The integers were coerced to floating-point in
order to evaluate the expressions.
We can combine the logic operators, comparisons and math. This
allows us to use comparisons and logic to prevent common mathematical
blunders like attempting to divide by zero, or attempting to take the
square root of a negative number.
For example, let's start with this program that will figure the
average of 95, 125 and 132.
sum = 95 + 125 + 132
count = 3
average = float(sum)/count
Initially, we set the variables
count. Then we compute the
Assume that the statement that computes the average
average=...), is part of a long and complex program.
Sometimes that long program will try to compute the average of no
numbers at all. This has the same effect as the following short
sum, count = 0, 0
average = float(sum)/count
In the rare case that we have no numbers to average we don't want
to crash when we foolishly attempt to divide by zero. We'd prefer to
have some more graceful behavior.
Recall from the section called “Truth and Logic” that the
operator doesn't evaluate the right-hand side
unless the left-hand side is
True. Stated the other
evaluates the right side if the left side is
can guard the division like this:
average = count != 0 and sum/count
This is an example that can simplify certain kinds of complex
processing. If the count is non-zero, the left side is true and the
right side must be checked. If the count is zero, the left side is
False, the result of the complete
This is a consequence of the meaning of the word
. The expression
a and b
a is true as well as
is true. If
a is false, the value of
b doesn't really matter, since the whole expression
is clearly false. A similar analysis holds for the word
. The expression
a or b
means that one of the two is true; it also means that neither of the two
is false. If
a is true, then the value of
b doesn't change the truth of the whole
The statement “It's cold and rainy” is completely
false when it is warm; rain doesn't matter to falsifying the whole
statement. Similarly, “I'm stopping for coffee or a
newspaper” is true if I've stopped for coffee, irrespective of
whether or not I stop for a newspaper.
Exact equality between floating-point numbers is a dangerous
concept. After a lengthy computation, round-off errors in floating point
numbers may have infinitesimally small differences. The answers are
close enough to equal for all practical purposes, but every single one
of the 64 bits may not be identical.
The following technique is the appropriate way to do floating
Rather than ask if the two floating point values are the same, we
ask if they're close enough to be considered the same. For example, run
the following tiny program.
Example 7.1. floatequal.py
# Are two floating point values really completely equal?
a,b = 1/3.0, .1/.3
When we run this program, we get the following output
0.333333333333 0.333333333333 False
The two values appear the same when printed. Yet, on most
False. They are not precisely the same. This is a
consequence of representing real numbers with only a finite amount of
binary precision. Certain repeating decimals get truncated, and these
truncation errors accumulate in our calculations.
There are ways to avoid this problem; one part of this avoidance
is to do the algebra necessary to postpone doing division operations.
Division introduces the largest number erroneous bits onto the trailing
edge of our numbers. The other part of avoiding the problem is never to
compare floating point numbers for exact equality.