Relational Operators
Relational Operators
Broadly speaking, operators in Python either “do stuff” or help us to write application logic.
On one hand, operators involved in arithmetic operations perform calculations while those involved in string operations transform text information.
On the other hand, there is a group of operators called relational operators which helps us to write application logic based on the relationship between two data values.
Relational operators can help us with application logic because they always evaluate to True or False. Just like how a complex road network can be built out of roads splitting off in two directions, application logic based on boolean values can help us build awesome programs.
The surprising thing about relational operators is that there are a number of different relationships that we can check for between two data values.
Ordering operators
For a start, relational operators can perform comparison between data values using the >, <, >=, <= operators. These four operators are called ordering operators because they can be used in sorting items of a list or dictionary etc.
Insertion order
To understand the term order in ordering operators, let us start by considering insertion order. Insertion order refers to the order in which items are added to a data value that can contain multiple other data values.
Below, we look at an unordered data type in earlier versions of Python — dictionaries and compare it with lists which are ordered:
- An unordered dictionary doesn’t remember its items’ insertion order whereas an ordered list does
- If we iterate over a dictionary like {‘a’: 1, ‘b’: 2}, the items could come out as (‘a’, 1), (‘b’, 2) or as (‘b’, 2), (‘a’, 1), whereas a list like [1,2,3] will always be [1,2,3] — for more info as to why dictionaries’ item order changes, see this post on Stackoverflow
- Note: dictionaries are ordered by default from Python 3.6 onwards
Other ways of ordering information
Insertion order is just one way of ordering the information we are storing in our data values.
Ordering operators approach ordering differently for data values of different data types. Here are some examples:
- Ordering operators order integers and floats by their numerical value from highest to lowest.
- On the other hand, ordering operators order strings from longest length to shortest length.
Left Operand — Ordering Operator — Right Operand
The fundamentals of ordering operations lie in the left operand — ordering operator — right operand code sequence.
Basically, ordering operators compare the order of their left operand versus the order of their right operand:
"a" > "b" <-- is order of character "a" larger than character "b"?
100 > 99.0 <-- is order of integer 100 larger than float 99.0?
Ordering operators comparing Integer / Float / Boolean values
Integers, Floats and Boolean values can be compared with each other based on their numerical value — True is implicitly converted to 1 and False to 0
# The following evaluates to True
False >= 0
True <= 1
10 < 10.1
Ordering operators comparing string characters
Individual string characters can be compared based on their ASCII code.
# ASCII code of character "a" is 97 and character "1" is 49
# The following evaluates to True"a" > "1"# note that we are comparing the character "a" with character "1" and not character "a" with number 1
Ordering operators comparing sequences
Sequences (referring to strings, lists and tuples) are compared from left to right —item by item, and by length if the items match.
However, the items being compared must be of the same data type, otherwise the operation would fail. (we cannot compare [1,2] with [“1”,”2"] for instance)
Ordering operators notes
Dictionaries don’t support ordering operators.
{"a":123} > {"a":121} # throws an error
Equality operators
The equality operators == and != compares between two data values to check if they store the same information.
One awesome feature of equality operators is its support for deep equality — which means nested items (eg. a list within a list within a list) are compared too.
# Lists
[1,2,(1,2,(2,5))] == [1,2,(1,2,(2,5))] # True
[1,2,(1,2,(2,3))] == [1,2,(1,2,(2,3))] # False# Dictionaries
{"a":12,"b":23,"c":{"d":34}} == {"a":12,"b":23,"c":{"d":34}} # True
{"a":12,"b":23,"c":{"d":34}} == {"a":12,"b":23,"c":{"d":35}} # False
Also, note that != produces the opposite effect of ==.
# Examples from above
[1,2,(1,2,(2,5))] != [1,2,(1,2,(2,5))] # False
{"a":12,"b":23,"c":{"d":34}} != {"a":12,"b":23,"c":{"d":35}} # True
In addition, the position of items in dictionaries don’t matter:
{"b":12,"a":123} == {"a":123,"b":12} #evaluates to True
Note that dictionaries support equality operators but not ordering operators.
Inclusion operators
The inclusion operators in and not in checks whether the right operand can be found inside a left operand which has to be a data value that can contain other data values (like strings, lists, tuples, dictionaries etc).
# The following examples evaluate to True
"a" in "abc" # string
"a" in ["a","b","c"] # list
"a" in ("a","b","c") # tuple
For a dictionary, inclusion operators check if an item corresponds to a key in the dictionary.
"a" in {"a":1,"b":2,"c":3} # evaluates to True
Note that not in produces the opposite effect of in.
# Examples from above
"a" not in "abc" # False
"a" not in {"a":1,"b":2,"c":3} # False
Order of operation
All relational operators have equal priority and are lower than those of arithmetic operators.
This means that a relational operator can be evaluated only if its two operands have been evaluated.
References
- Python.org docs on data structures
- Stackoverflow post on ordering in dictionaries
- Stackoverflow post on why dictionaries item order changes
- Article by Mr Trey Hunner on deep comparison in Python data structures
Summary
- Relational operators comprise of four ordering operators (>, <, >=, <=), two equality operators (==, !=) and two inclusion operators (in, not in)
- Relational operators always evaluate to True or False
- There are different ways of ordering data values from insertion order (in lists etc), numerical values (between integers, floats etc) to character ASCII code or string length (between strings)
- Nested data values are also taken into account — Ordering operators support deep comparison and Equality operators support deep equality
Quiz
Which of the following options are correct?
a) = is a relational operator
b) “a” not in “abc” evaluates to False
c) “a” >= “A” evaluates to True
d) [“a”, “b”, [“a”,”b”]] > [“a”, “b”, “c”] evaluates to False
Quiz Explanation
a) = is assignment operator, not relational operator. Also, operands and = operator don’t evaluate to True or False.
b) The in operator checks whether the left operand “a” can be found inside the right operand “abc” which evaluates to True. The not in operator is opposite of the in operator which means “a” not in “abc” evaluates to False.
c) In “a” >= “A”, we are checking whether the ASCII code of character “a” is larger than ASCII code of character “A” which will evaluate to True. (“a” has ASCII code of 97 and “A” 65)
d) [“a”,”b”] cannot be compared against “c” as they are of different data types.
Quiz answers: b & c