-2

I am trying to understand what mechanism is used by in to compare the needle and the haystack.

  1. [] in ([],[],[]) is True, so it cannot be is, because [] is [] is False
  2. But math.nan in ([],[],math.nan) is True, too, so it cannot be ==, because math.nan==math.nan is False.

If it is neither == (comparison for equal value) nor is (comparison for object identity), what is it?

DYZ
  • 55,249
  • 10
  • 64
  • 93

1 Answers1

3

As the docs say:

For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).

So, it's both.

bereal
  • 32,519
  • 6
  • 58
  • 104
  • Anyway to see that using `dis.dis`? Or do you just need to know that when you see `(in)`, it is the implemented as any? – dfundako Jan 26 '21 at 20:52
  • @dfundako no, `is` is absolutely **not** implemented as `any`. And you couldn't see this with `dis.dis`, it will just show that you are using the binary operator `is`. It is *equivalent* to that. – juanpa.arrivillaga Jan 26 '21 at 20:54
  • 1
    @dfundako internally, lists are implemented in C, so you can't see that in `dis`. For non-builtin containers, you can check `__contains__`. – bereal Jan 26 '21 at 20:55
  • 1
    @dfundako: It's using [`PyObject_RichCompareBool`](https://docs.python.org/3/c-api/object.html#c.PyObject_RichCompareBool) deep in the C layer; you wouldn't see it with `dis`. That's a C optimized test that's explicitly documented to short-circuit for `==`/`!=` based on identity. – ShadowRanger Jan 26 '21 at 20:57