# Why does __ne__ exist?

```On 07/01/2018 19:55, Chris Angelico wrote:

> Under what circumstances would you want "x != y" to be different from
> "not (x == y)" ? How would this make for sane behaviour?

Presumably so that any behaviour any be programmed when overriding these
operators.

Maybe someone wants to do weird stuff with == that doesn't yield a true
or false result, so that you can't just reverse it for !=.

For example (perhaps this is similar to what was suggested in another post):

(10,20,30) == (10,20,40)   yields  (1,1,0)
(10,20,30) != (10,20,40)   yields  (0,0,1)

Although here, you would probably define 'not' so that 'not (1,1,0)'
does actually yield '(0,0,1)'.

So clearly I need a weirder example.

Even when
> other things go weird with equality checks, that basic parallel is
> always maintained:
>
>>>> z = float("nan")
>>>> z == z
> False
>>>> z != z
> True
>
> Python gives us a "not in" operator that uses __contains__ and then
> negates the result. There is no way for "x not in y" to be anything
> different from "not (x in y)", as evidenced by the peephole optimizer:
>
>>>> dis.dis("x not in y")
>    1           0 LOAD_NAME                0 (x)
>                4 COMPARE_OP               7 (not in)
>                6 RETURN_VALUE
>>>> dis.dis("not (x in y)")
>    1           0 LOAD_NAME                0 (x)
>                4 COMPARE_OP               7 (not in)

I get '4 COMPARE OP    6 (in)' here. So they are distinct ops. 'not in'
doesn't just call 'in', then apply 'not'. Not here anyway.

--
bartc

```