The Python Language Reference, Release 3.9.5 6.10.1 Value comparisons The operators$_{<}$ ,$_{>}$ ,$_{==}$ ,$_{>=}$ ,$_{<=}$ , and$_{!=}$ compare the values of two objects. The objects do not need to have the same type. Chapter Objects, values and types states that objects have a value (in addition to type and identity). The value of an object is a rather abstract notion in Python: For example, there is no canonical access method for an object’s value. Also, there is no requirement that the value of an object should be constructed in a particular way, e.g. comprised of all its data attributes. Comparison operators implement a particular notion of what the value of an object is. One can think of them as defining the value of an object indirectly, by means of their comparison implementation. Because all types are (direct or indirect) subtypes of object , they inherit the default comparison behavior from object . Types can customize their comparison behavior by implementing rich comparison methods like __lt__() , described in Basic customization . The default behavior for equality comparison ($_{==}$ and$_{!=}$ ) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e. x is y implies x == y ). A default order comparison ( < , > , <= , and >= ) is not provided; an attempt raises TypeError . A motivation for this default behavior is the lack of a similar invariant as for equality. The behavior of the default equality comparison, that instances with different identities are always unequal, may be in contrast to what types will need that have a sensible definition of object value and value-based equality. Such types will need to customize their comparison behavior, and in fact, a number of built-in types have done that. The following list describes the comparison behavior of the most important built-in types. • Numbers of built-in numeric types (typesnumeric) and of the standard library types fractions. Fraction and$_{decimal.Decimal}$ can be compared within and across their types, with the restriction that complex numbers do not support order comparison. Within the limits of the types involved, they compare mathematically (algorithmically) correct without loss of precision. • None and$_{NotImplemented}$are singletons. PEP 8 advises that comparisons for singletons should always be done with$_{is}$ or$_{is not}$, never the equality operators. • Binary sequences (instances of$_{bytes}$or$_{bytearray}$) can be compared within and across their types. They compare lexicographically using the numeric values of their elements. • Strings (instances of$_{str}$) compare lexicographically using the numerical Unicode code points (the result of the built-in function$_{ord()}$ ) of their characters. 3 • Sequences (instances of$_{tuple}$ ,$_{list}$, or$_{range}$) can be compared only within each of their types, with the restriction that ranges do not support order comparison. Equality comparison across these types results in inequality, and ordering comparison across these types raises$_{TypeError}$. Sequences compare lexicographically using comparison of corresponding elements. The built-in containers typically assume identical objects are equal to themselves. That lets them bypass equality tests for identical objects to improve performance and to maintain their internal invariants. Strings and binary sequences cannot be directly compared. The not-a-number values$_{float('NaN')}$ and$_{decimal.Decimal('NaN')}$ are special. Any ordered comparison of a number to a not-a-number value is false. A counter-intuitive implication is that not-a-number values are not equal to themselves. For example, if$_{x = float('NaN')}$ ,$_{3 < x}$ ,$_{x < 3}$ and$_{x == x}$ are all false, while$_{x != x}$ is true. This behavior is compliant with IEEE 754. 3 The Unicode standard distinguishes between code points (e.g. U+0041) and abstract characters (e.g. “LATIN CAPITAL LETTER A”). While most abstract characters in Unicode are only represented using one code point, there is a number of abstract characters that can in addition be represented using a sequence of more than one code point. For example, the abstract character “LATIN CAPITAL LETTER C WITH CEDILLA” can be represented as a single precomposed character at code position U+00C7, or as a sequence of a base character at code position U+0043 (LATIN CAPITAL LETTER C), followed by a combining character at code position U+0327 (COMBINING CEDILLA). The comparison operators on strings compare at the level of Unicode code points. This may be counter-intuitive to humans. For example, "\u00C7" == "\u0043\u0327" is False , even though both strings represent the same abstract character “LATIN CAPITAL LETTER C WITH CEDILLA”. To compare strings at the level of abstract characters (that is, in a way intuitive to humans), use unicodedata.normalize() . 77 6.10. Comparisons