The answer here gives a handwaving reference to cases where you'd want __ne__
to return something other than just the logical inverse of __eq__
, but I can't imagine any such case. Any examples?

- 1
- 1

- 11,414
- 4
- 32
- 37
-
7At least for `>` and `<=` there are such cases. Namely `NaN < anything => false` and `NaN >= anything => false`. (Assuming python follows IEEE floating point logic) – CodesInChaos Feb 26 '12 at 11:04
-
3Yep basically anything that doesn't have a [total order](http://en.wikipedia.org/wiki/Total_ordering) can fall into that category. Now those things are kinda rare for obvious reasons, but they do exist. NaNs are a nice example. – Voo Feb 26 '12 at 11:09
-
5But even for `NaN` it holds at least in python: `NaN != NaN => True`, `NaN == NaN => False`. – Has QUIT--Anony-Mousse Feb 26 '12 at 11:37
-
The fact that `equals` (`__eq__`) _may not_ return a `Boolean` type and that `not equals` (`__ne__`) _may not_ be the opposite of equals... defies all intuition. -- I accept it as the Python way. I guess it has its benefits as explained by the answers. Yet, for newcomers to the language, this is eerie. – juanmirocks Nov 11 '16 at 09:31
3 Answers
SQLAlchemy is a great example. For the uninitiated, SQLAlchemy is a ORM and uses Python expression to generate SQL statements. In a expression such as
meta.Session.query(model.Theme).filter(model.Theme.id == model.Vote.post_id)
the model.Theme.id == model.VoteWarn.post_id
does not return a boolean, but a object that eventually produces a SQL query like WHERE theme.id = vote.post_id
. The inverse would produce something like WHERE theme.id <> vote.post_id
so both methods need to be defined.

- 104,512
- 31
- 200
- 194
Some libraries do fancy things and don't return a bool from these operations. For example, with numpy:
>>> import numpy as np
>>> np.array([1,2,5,4,3,4,5,4,4])==4
array([False, False, False, True, False, True, False, True, True], dtype=bool)
>>> np.array([1,2,5,4,3,4,5,4,4])!=4
array([ True, True, True, False, True, False, True, False, False], dtype=bool)
When you compare an array to a single value or another array you get back an array of bools of the results of comparing the corresponding elements. You couldn't do this if x!=y
was simply equivalent to not (x==y)
.

- 17,058
- 3
- 60
- 75
-
1I can't follow that. Considering that `not` is defined on an array of bools in the obvious way, we still don't need `neq` instead of `not equals`. But clearly there's a performance and possible memory advantage there. – Voo Feb 26 '12 at 18:12
-
7While a good argument could be made for a `__not__` special method to override the `not` operator, this does not currently exist in Python. – Weeble Feb 26 '12 at 18:50
-
1Oh that's surprising.. yeah in that case it's not only a matter of performance. Thanks! – Voo Feb 26 '12 at 19:07
-
@Weeble Unary invert ([`__invert__`](https://docs.python.org/3/reference/datamodel.html#object.__invert__)) works: `~np.array([True, False])` -> `array([False, True])`. Though I'm not sure if it was the same back in 2012. – wjandrea Aug 04 '20 at 03:58
More generally, in many valued logic systems, equals
and not equals
are not necessarily exact inverses of each other.
The obvious example is SQL where True == True
, False == False
and Null != Null
. Although I don't know if there are any specific Python examples I can imagine it being implemented in places.

- 51,770
- 36
- 127
- 149
-
1And in MYSQL, you can even have values that are `NULL` and `NOT NULL` at the same time!!!1! (I consider that a design bug of MySQL though) – Has QUIT--Anony-Mousse Feb 26 '12 at 20:31