Python Part I · Module 3 · Operators and Expressions
Comparisons: == != < <= > >=
Every expression so far has produced a number. This chapter produces something else: a yes-or-no answer. Comparing two values gives you back True or False — the boolean values from Module 2 — and that turns out to be the foundation of everything a program does that looks like making a decision. The chapter covers the six comparison operators, but it spends most of its attention on one distinction, because it is the single most common source of confusion for people new to programming and it produces errors that are occasionally silent. One equals sign stores a value under a name. Two equals signs ask whether two values are the same and hand you the answer. They look almost identical and they do entirely different things.
Foundation11 min readPythonPart IFundamentalsComparisonbool
Part I · Module 3 · Chapter 3.4 · Comparisons: == != < <= > >=
1. A Comparison Produces a Value
print(3 < 7)
print(3 > 7)True
False3 < 7 is an expression, exactly as 3 + 7 is. Python evaluates it and produces a value — and this time the value is a bool, one of the two from Chapter 2.8.
print(type(3 < 7))<class 'bool'>That is the whole idea of the chapter. A comparison is not a special kind of code. It is an expression whose result happens to be True or False.
Which means you can store it under a name, exactly as you would a number:
error_count = 0
is_clean = error_count == 0
print(is_clean)Trueis_clean now refers to True. No decision has been made — nothing has acted on that answer. It is a value sitting under a name, waiting.
2. The Six Operators
print(5 == 5)
print(5 != 5)
print(5 < 9)
print(5 <= 5)
print(5 > 9)
print(5 >= 5)True
False
True
True
False
True| Operator | Asks | 5 ? 5 | 5 ? 9 |
|---|---|---|---|
== | are these equal? | True | False |
!= | are these different? | False | True |
< | is the left smaller? | False | True |
<= | smaller or equal? | True | True |
> | is the left larger? | False | False |
>= | larger or equal? | True | False |
Two notes on the symbols. != uses an exclamation mark to mean not, so it reads as "not equal". And <= is written in that order, never =<.
3. One Equals Sign or Two
This is the part of the chapter worth slowing down for.
= stores. Module 2 taught this: error_count = 0 points the name error_count at the value 0. It is an instruction, it performs an action, and it produces no value you can print.
== compares. error_count == 0 asks whether the value error_count refers to is equal to 0, and produces True or False.
error_count = 0 # store: point the name at 0
print(error_count == 0) # compare: is it equal to 0?
print(error_count)True
0What happens if you use the wrong one
error_count = 0
print(error_count = 0)TypeError: print() got an unexpected keyword argument 'error_count'The message is not obvious, but the cause is: print() was handed something that is not an expression. Assignment is an action, so it cannot go where a value is expected — the test from Chapter 3.1 §4.
Python catches this one. It does not catch every case, which is why the habit of reading = as "is assigned" is worth building now.
4. Comparing Different Kinds of Value
Numbers compare as you would expect, including across int and float:
print(5 == 5.0)
print(10 / 2 == 5)True
True5 and 5.0 are different types — Chapter 2.6 §2 — but they represent the same quantity, and == compares the values rather than the types.
Text compares too, and == on two strings asks whether they contain the same characters:
print("PASS" == "PASS")
print("PASS" == "FAIL")
print("PASS" == "pass")True
False
FalseThat last one is worth noticing: comparison is case-sensitive, exactly as names are. "PASS" and "pass" are different text.
Comparing across types that do not order
Equality works between any two values. Ordering does not:
print(3 < "5")TypeError: '<' not supported between instances of 'int' and 'str'Python refuses rather than guessing what you meant. "5" is text — Chapter 2.9 §3 — and there is no sensible answer to whether a number is smaller than a piece of text.
Note that == does not fail here; it simply answers False:
print(3 == "3")FalseA number and a piece of text are never equal, however similar they look. This is the identical-output distinction from Chapter 2.1, now answerable in one line.
5. Comparing Floats Needs Care
print(0.1 + 0.2 == 0.3)FalseThat is not a bug, and Chapter 2.6 §5 explained why: 0.1 has no exact binary representation, so 0.1 + 0.2 is a value extremely close to 0.3 but not identical to it. == asks for exact equality and gets an honest False.
print(0.1 + 0.2)0.300000000000000046. Chained Comparisons
Python lets you write a range check the way mathematics does:
value = 100
print(0 <= value <= 255)TrueThat reads as is value between 0 and 255 inclusive, and it means exactly that. Most languages require two separate comparisons joined together; Python allows the chain directly.
value = 300
print(0 <= value <= 255)FalseUseful, and worth recognising when you read it. Chapter 3.5 shows the other way of writing the same idea.
7. Predict, Run, Observe
Predict value and type for each.
total = 600
passed = 589
print(passed == total)
print(passed != total)
print(passed < total)
print(total - passed == 11)
print(type(passed < total))
print("PASS" == "PASS")
print(1 == 1.0)False
True
True
True
<class 'bool'>
True
TrueThe fourth line is the interesting one: total - passed was evaluated first — producing 11 — and then compared against 11. Arithmetic before comparison, which Chapter 3.8 puts on a formal footing.
8. Exercise
Exercise 1 — store the answer. Given coverage = 94.5 and a threshold of 95.0, write one line that stores whether coverage has reached the threshold, and print it. No if — just produce the value.
Exercise 2 — say it correctly. Write one sentence each describing what these two lines do. The sentences should not be interchangeable:
error_count = 0
error_count == 0Exercise 3 — predict six. Given a = 10 and b = 3, predict each, then run:
(a) a == b (b) a != b (c) a > b (d) a // b == 3 (e) a % b == 1 (f) a / b == 3
Explain (f) in one sentence.
Exercise 4 — the type refusal. Predict what each does, then run:
(a) print(5 == "5") (b) print(5 < "5")
One answers, one fails. Explain the difference in one sentence.
Exercise 5 — the float trap. Predict, then run:
print(0.1 + 0.2 == 0.3)
print(1.5 + 1.5 == 3.0)Both involve floats and only one is False. Say why in one sentence.
9. Summary
- A comparison is an expression producing a
bool—TrueorFalse. It can be printed or stored like any other value. - Six operators:
==equal,!=different,<<=>>=for ordering. =assigns;==compares. Read=as "is assigned" and the confusion disappears. Using=where a value is expected is an error.==compares values, not types —5 == 5.0isTrue. But a number is never equal to text:3 == "3"isFalse.- Ordering across unrelated types fails with a
TypeError, rather than guessing. - Text comparison is case-sensitive.
- Exact
==between computed floats is unreliable —0.1 + 0.2 == 0.3isFalse. Threshold comparisons are fine. - Chained comparisons work:
0 <= value <= 255means what it looks like.
You can now produce a yes-or-no answer about two values. The next chapter combines several of those answers into one.
Where this fits
Part of the Python curriculum.
