7

I have some code here:

m = None
n = None

if not m:
    print "Something happens"
>>> Something happens

if I do:

if not m and n:
    print "Something happens"

Nothing happens.

But I can do:

m, n = 1,2
if m and n:
    print "Something happens"
>>> Something happens

Why are if and if not handled the same way? Does 'if not', not take 'and' statements?

Thank you

1
  • I have seen somewhere that it is a good practice to compare to None using identity. e.g.: if m is None and n is not None:. Commented Apr 20, 2012 at 9:12

3 Answers 3

16

You have an operator precedence problem.

if not m and n is equivalent to if (not m) and n. What you want is if not m and not n or if not (m or n).

See also: De Morgan's Laws

Sign up to request clarification or add additional context in comments.

3 Comments

When in doubt, parenthesize. I sometimes wonder how much time would be saved if languages required you to use explicit grouping in any condition where there might be a question. You'd spend a few seconds typing extra (), but you'd save so much more the first time it avoided confusing stuff like this. Then you'd waste twice as much time sitting around the water-cooler bitching about all the () in this stupid language...
Just thought I would add the term: operator precedence - docs.python.org/reference/expressions.html#summary.
@MichaelJ.Barber hehe, although unintentional the biggest complaint about Lisp IS all the (), so my theory was correct :)
7

I think you are looking for this article: Truth Value Testing

Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:

  • None
  • False
  • zero of any numeric type, for example, 0, 0L, 0.0, 0j.
  • any empty sequence, for example, '', (), [].
  • any empty mapping, for example, {}.
  • instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False.

All other values are considered true — so objects of many types are always true. Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)

Especially the next chapter explains your case (Boolean Operations — and, or, not):

not has a lower priority than non-Boolean operators

Comments

2

not applied to its closet operand. You wrote if not m and n where not applies to m which is True, and because of and, n is evaluate to False, hence the entire statement is evaluated to False.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.