Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Python need rich comparison?

Tags:

python

There is a confusion for me for some time: is there a scene that we do need to use rich comparison in Python?

I read the official doc here, but it only gives how it works not why we need it.

A snippet of the doc:

The truth of x==y does not imply that x!=y is false. may describe a scene that we need rich comparison. In this scene, we can make __eq__ and __ne__ both return False for disabling the comparsion or any other purpose. (We can implement this by using __cmp__)

But this just a guess, I have never encountered such a requirement in a real project yet.

Does anyone need to use rich comparison indeed or is there any other scenario where we need to use rich comparison in theory?

Maybe my example of x==y and x!=y caused some confusion, sorry for that. Let me make it a bit clearer:
Are there any scenario where rich comparison can help but __cmp__ can not?

like image 554
WKPlus Avatar asked Jan 08 '14 07:01

WKPlus


2 Answers

NumPy uses rich comparisons to vectorize ==, !=, <, etc, just like it does with most other operators. For example,

>>> x = numpy.array([1, 2, 3, 4, 5])
>>> y = numpy.array([2, 2, 1, 4, 4])
>>> x == y
array([False,  True, False,  True, False], dtype=bool)

When arrays x and y are compared with any comparison operator, NumPy applies the operator (roughly) elementwise and returns an array of results. This is useful, for example, to apply an operation to the cells of x that fit the condition:

>>> x[x==y] = 6
>>> x
array([1, 6, 3, 6, 5])

Here, I've selected all elements of x that equal the corresponding elements of y, and set them equal to 6.

like image 181
user2357112 supports Monica Avatar answered Nov 01 '22 03:11

user2357112 supports Monica


You don't even need to return boolean values. The point the documentation is making is that you are given total freedom over what the overloaded methods can return; Python does not enforce that __eq__ and __ne__ return consistent boolean values.

The SQLAlchemy project has overloaded the rich comparison operators altogether to return something else entirely. If you use:

model1.column == model2.column

or

model1.column != model2.column

or

model1.column < model2.column

where model1 and model2 are both SQLAlchemy table models then you don't get a boolean value, what you get is a SQL query filter instead.

You use the return values to construct SQL queries:

model1.filter(model1.column <= model2.column)

would result in a SQL query along the lines of:

select model1.*
from model1
left join model2 on model1.foreign_key == model2.primary_key
where
    model1.column <= model2.column

entirely in Python code, using Python rich comparison syntax.

like image 40
Martijn Pieters Avatar answered Nov 01 '22 03:11

Martijn Pieters