2

I have a function that returns False if something isn't found, and returns a data structure with what I'm looking for otherwise. When I assign the value returned from this function to a variable my_var in a for loop, I do a if my_var == False: continue to carry on.

pychecker doesn't like this and reports Comparisons with False are not necessary and may not work as expected.

What's the python way for doing this?

kiminoa
  • 2,649
  • 3
  • 16
  • 17

5 Answers5

3

As a return value indicating absence of a result, None is almost always better.

  • If you must use False, use not my_var. This assumes non - False return values are never "falsy" (bool() converts it into False - this is the case for empty strings, empty collections, and a few other things).

  • If objects may be falsy but must be distinguished from False, then the comparison is necessary and you'll have to ignore the error (a minor variation, my_var is False would be slightly more idiomatic, but it's virtually the same). But that's not a nice situation to be in and you should avoid it for the fake of clarity.

To repeat myself: If at all possible, use None and test for my_var is None.

wrhall
  • 1,288
  • 1
  • 12
  • 26
3

Normally you would return None instead of False i.e. if an object doesn't match. And then check if my_var == None: as all not 0, not False and not None return True.

emil
  • 1,642
  • 13
  • 12
2

If you just want to check for a falsy value:

myval = findit('something')
if not myval:
   "not found"

You don't want to do this if you could actually return a value for the "is-found" case which has a falsy value. E.g., if [] (empty list) is found, this will still report "not found".

If you care that it is actually False, use is. True, False, and None are singletons, so the identity comparison operator is used.

if myval is False:
   "not found"

In this case you are using False as a sentinel value to indicate that there is no result.

Usually None is used as a sentinel "no-value", however, so I suggest you change the signature of your function to return None if no value is found. This conforms better with Python idiom and the behavior of methods such as {}.get('missing-key').

myval = findit('something')
if myval is None:
    "not found"

In cases where no sentinel value is possible because any value could be returned (even None or False), Python uses an exception to signal that no value was found. E.g. {}['missing-key'] will raise KeyError.

Francis Avila
  • 31,233
  • 6
  • 58
  • 96
1

Usually you'd just use not:

if not my_var: continue
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • If the datastructure returned might be falsy, this may match too much. – Francis Avila Mar 05 '13 at 16:38
  • @FrancisAvila If that's the case then one could test if the value in `my_var` has type `bool` -- however, one would hope that objects and bools aren't being mixed in the data structure... – cdhowie Mar 05 '13 at 16:41
  • What I mean is `(not []) == True`. If his function could return an empty list or string or 0 (or any object which has a magic method giving it a false value), then this will surprise him. – Francis Avila Mar 05 '13 at 16:42
  • @FrancisAvila Right, I know what you're saying. I'm saying that having lists and bools on the same level of a structure is not a good idea. :) – cdhowie Mar 05 '13 at 16:43
  • 1
    That's exactly what the OP's function is doing. Datastructure (e.g. `[]`) if "found", `False` if "not found". He's using False as a sentinel value. – Francis Avila Mar 05 '13 at 16:45
1

Python is actually more strongly typed than C++ in this regard. Only genuine booleans can be True or False.

So my_var must be a boolean. Therefore you just check it as one.

if not my_var:
     continue
CashCow
  • 30,981
  • 5
  • 61
  • 92
  • Since the variable could equally be a data structure, I think I'm not respecting the idea of a genuine boolean. The data structure would return True if evaluated, but what you're saying is that it's kind of an abuse of polymorph power, yes? – kiminoa Mar 05 '13 at 16:46
  • By "strongly typed", do you mean "less inclined to do implicit conversions"? Then please say that instead of the [ill-defined-to-the-point-of-meaninglessness word](http://stackoverflow.com/a/9929697/395760) that is "{strongly, weakly} typed". –  Mar 05 '13 at 16:46
  • Yes, I mean that. Python uses dynamic typing but avoids implicit conversions. – CashCow Mar 05 '13 at 16:55