1

I need to check if a function written by another team returns True or None.

I want to check for identity, not equality.

I'm unclear what type of check happens when using in. Which of the following does if result in (True, None): behave like?

  1. if result is True or result is None:

  2. if result or result == None:

Jeff Widman
  • 22,014
  • 12
  • 72
  • 88

2 Answers2

3

No, they are not the same, because identity testing is a subset of what the in operator does.

if result in (True, None):

Is the same as this:

if result == True or result is True or result == None or result is None:
# notice that this is both #1 and #2 OR'd together

From the docs:

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)

The in operator tests for both equality and identity, and either one being true will return True. I got the impression that you're only working with boolean values and None. In that limited case, the in operator will behave the same as both of your other snippets.

However, you said you want identity checking. So I would suggest you use that explicitly so your code's intention and what it is expecting is clear. Furthermore, if there is a bug in the called function and it returns something other than boolean or None, using the in operator can hide that bug.

I would suggest your first alternative:

if result is True or result is None:
    # do stuff
else:
    # do other stuff

Or if you're feeling defensive:

if result is True or result is None:
    # do stuff
elif result is False:
    # do other stuff
else:
    # raise exception or halt and catch fire
skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
  • 3
    "`if result in (True, None)` will behave the same as both of your other code examples." - no it won't. It won't behave like the first snippet because other things can be equal to `True` and `None`. For example, `1.0 == True`. It won't behave like the second snippet because that snippet treats `result` as a boolean directly instead of comparing it to `True` with `==`. – user2357112 Nov 29 '16 at 00:54
  • I think it's more intuitive to check the identity explicitly rather using the membership operator... – Jeanderson Candido Nov 29 '16 at 00:56
  • 2
    @user2357112 I got the impression that the only possible return values are `True`, `False`, and `None`. If that's the case, then they will behave the same. – skrrgwasme Nov 29 '16 at 00:57
  • Thanks, this is helpful. Can you reorder your answer slightly to make it clear they aren't the same and the `in` operator behaves like the 2, not 1? I'll happily accept it then. – Jeff Widman Nov 29 '16 at 01:01
  • @JeffWidman I've reworded it to hopefully make it more clear, but I have to correct your last comment: it's not more like #1 *or* #2. It's **both**. – skrrgwasme Nov 29 '16 at 01:16
0

You want to use the identity operator (is) and not the membership operator (in):

> 1 == True
True
> 1 is True
False
> 1 in (True, None)
True

This is a "TL;DR" complement to @skrrgwasme answer :)

  • sorry if you meant I copied your original work but we posted around the same time and by the time I posted, your answer wasn't full of editions ;) – Jeanderson Candido Nov 29 '16 at 16:34
  • I wrote this on my console. Is there anyway to see the history of deleted comments? I honestly don't recall anyone posting this code snippet neither more than two answers on the thread. – Jeanderson Candido Nov 29 '16 at 16:59
  • Fair enough - sorry for the accusation. I'll remove the downvote if you make a small edit. (I can't change my vote until it's edited.) – skrrgwasme Nov 29 '16 at 17:12
  • that's fine mate, actually think this is a complement to your answer. there are more in-depth arguments in your answer. mine is more a "TL;DR" – Jeanderson Candido Nov 29 '16 at 17:16