Extreme Python

Logo

Extremely good python content :)

About

Articles

Python Comparison Operators

by Alan

Python provides the following object comparison operators:

Here’s three key facts about the operators above:

  1. The is and is not operators always compare by identity. Subtypes cannot override this behavior.
  2. The behavior == and != operators are implemented by the base object and compare by identity by default. Subtypes can override this behavior (most built-in types do, as you’ll see later).
  3. All other operators are not implemented by the base object. Subtypes are solely responsible for defining the behavior of <, <=, >, and >=.

Since the operators is and is not have the same behavior all the time (compare by identity), I will be focusing on the behavior of the other operators in this post since they’re type-dependant. Any time I use the term “comparison operators” from this point on, assume I’m referring to everything except for is and is not.

Numerics

All comparisons of numeric types are based on value.

>>> a = 123.0
>>> b = 123
>>> a == b
True
>>> a < b
False

Even though a and b point to two different objects (the former is a float and the latter is an integer), comparing them with == returns true because number objects override that operator to compare by value instead of identity (the default).

Can you compare across different types in general?

Comparisons across different types isn’t supported outside of numeric types.

In python 3.x, you’ll get an type error if you attempt to compare different types. Python 2.x is more forgiving and does return a value but the behavior (while consistent) is not part of the language spec.

Ordered containers (also known as sequences)

Sequences use “lexicographical comparison”, which is based on lexicographical order.

Examples:

>>> 'alan' < 'alba'
True
>>> 'alan' < 'alan'
False
>>> [1, 2, 3] < [3, 2, 1]
True
>>> [99, 2, 3] < [3, 2, 1]
False
>>> [1, 2, 3] == [1, 2, 3]
True

In the first example, alan comes before alba because first and second characters are equal, but since the third letter a appears in the alphabet earlier than b, alan comes first.

Unordered containers (maps and sets)

Maps (dictionary)

Maps compare equal if and only if they have equal key-value pairs. The comparison operators <, >, <=, and >= raise TypeError.

>>> {1, 2} == {2, 1}
True
>>> {} == {}
True
>>> {'a': 'b'} == {}
False
>>> {'a': 'b'} == {'a': 'b'}
True
>>> {'a': 'b'} == {'a': None}
False
>>> {} < {}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'

Sets

All comparison operators are actually subset and superset tests:

Examples:

>>> {} == {}
True
>>> {1} < {5}
False
>>> {1} > {5}
False
>>> {1} < {1}
False
>>> {1} < {2, 1}
True
>>> {1} < {2, 1, 3}
True
>>> {1, 2} < {2, 1, 3}
True
>>> {1, 2, 3} < {2, 1, 3}
False
>>> {1, 2, 3, 5} < {2, 1, 3}
False
>>> {1, 2, 3, 5} > {2, 1, 3}
True
tags: