0

I am trying to find all None elements in an array using np.where. This is my code:

a = np.array([None, 1, 2, None, 3])
print(np.where(a is None)[0])
print(np.where(a == None)[0])

Oddly, using "a is None" returns an empty array, while using "a==None" returns the correct result. I wonder why this is happening? Thanks!

Update: If a is a python list, then both will behave the same and return []. The difference will only happen when a is cast to an ndarray.

edwardliang2019
  • 302
  • 2
  • 9
  • 1
    Does this answer your question? [Is there a difference between "==" and "is"?](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is) – PCM Jul 19 '21 at 03:56
  • Both lines should be executed as `print(np.where(False)[0])`. – Klaus D. Jul 19 '21 at 04:14
  • I've edited the code. Turns out casting a to an ndarry will result in the behavior I described, while keeping it as a list will cause both lines to return []. – edwardliang2019 Jul 19 '21 at 04:18
  • 2
    Operator "is" can't be overloaded and always checks identity while "==" can be (and is here) overloaded to produce a result which can be further processed by "np.where". – Michael Butscher Jul 19 '21 at 04:21

1 Answers1

2

a is None checks whether a itself is None, and does NOT check the elements of a against None. In other words, a is None if a itself is None. So, a is None returns False here since a is not empty. Now, np.where(a is None) is equivalent to np.where(False) which is empty and hence its first element is empty as well, returning [].

On the other hand a == None checks elements of a against None and will return array([ True, False, False, True, False]) which results in the output you see.

In short:

a is None
#False

a == None
#array([ True, False, False,  True, False])
Ehsan
  • 12,072
  • 2
  • 20
  • 33
  • Thanks Ehsan. Combining you answer with Michael Butscher's comment above, is my following understanding correct? If a is a Python list, then both "is None" and "== None" will check if a itself is None. If a is an ndarray, then for '==', because it is overloaded for ndarray, it can achieve element-wise comparison, while "is None" cannot be overloaded, so it won't have the same effect. – edwardliang2019 Jul 19 '21 at 05:52
  • 1
    @edwardliang2019 For a list `==` is also overloaded but the implementation only returns True if the object to compare with is also a list of same length and contains items in same order which are equal to the respective items of a. It returns False otherwise. – Michael Butscher Jul 19 '21 at 21:49