3

I'm learning Python and I just started learning conditionals with booleans

I am very confused though as to the specific topic of "If Not". Could someone please explain to me the difference between :

x = False

if not x:
   print("hello")

if x == False:
   print("hello")

When testing this code on a Python compiler, I receive "hello" twice. I can assume this means that they both mean the same thing to the computer.

Could someone please explain to me why one would use one method over the other method?

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 3
    Please repeat [on topic](https://stackoverflow.com/help/on-topic) and [how to ask](https://stackoverflow.com/help/how-to-ask) from the [intro tour](https://stackoverflow.com/tour). You're asking for a personal tutorial on a topic that is covered quite thoroughly in other places. See [How much research?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users). – Prune Jun 01 '21 at 17:57
  • 1
    Also, read about `bool(x)` and `__bool__` – Mad Physicist Jun 01 '21 at 17:59
  • 1
    I think this question is on topic. its not obvious what the difference between these two forms are. An optimizing compiler in a highly typed language might devolve these two statements to the same bit of code, but python doesn't. And its pretty fundamental to the language why. – tdelaney Jun 01 '21 at 18:15
  • @Prune I was learning about if not statements from CodeAcademy, yet the topic still confused me and I wasn't able to wrap my head around it. I looked around StackOverflow for answers, but none could answer what I specifically had in mind. I'm sorry if me asking this type of question upset you though, and I'll keep those terms in mind when asking another question. – WillPak_Alt Jun 01 '21 at 18:20
  • @Prune If the question has been covered thoroughly elsewhere, that's irrelevant. If it has been covered thoroughly *here*, please share the recommended duplicate target. – TylerH Jun 01 '21 at 18:26
  • 1
    No, it's not irrelevant. Again, see the posting guidelines to which I linked. – Prune Jun 01 '21 at 18:29
  • @Prune It is irrelevant; lack of research is a downvote reason, not a close-vote reason. – TylerH Jun 01 '21 at 18:43

4 Answers4

4

It depends™. Python doesn't know what any of its operators should do. It calls magic methods on objects and lets them decide. We can see this with a simple test

class Foo:
  
    """Demonstrates the difference between a boolean and equality test
    by overriding the operations that implement them."""
    def __bool__(self):
        print("bool")
        return True

    def __eq__(self, other):
        print("eq", repr(other))
        return True

x = Foo()

print("This is a boolean operation without an additional parameter")
if not x:
    print("one")

print("This is an equality operation with a parameter")
if x == False:
    print("two")

Produces

This is a boolean operation without an additional parameter
bool
This is an equality operation with a parameter
eq False
two

In the first case, python did a boolean test by calling __bool__, and in the second, an equality test by calling __eq__. What this means depends on the class. Its usually obvious but things like pandas may decide to get tricky.

Usually not x is faster than x == False because the __eq__ operator will typically do a second boolean comparison before it knows for sure. In your case, when x = False you are dealing with a builtin class written in C and its two operations will be similar. But still, the x == False comparison needs to do a type check against the other side, so it will be a bit slower.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • I'm not so sure as to what the code you wrote necessarily means up until the if statements, but as for the explanation for "speed", it does help a lot. Thank you very much. :D – WillPak_Alt Jun 01 '21 at 18:16
  • Not sure if the additional comments help. `Foo` is a class that overrides the magic methods used in your test. It gets more complicated because python also has fallback rules for classes that don't have a given magic method. The default `object` object implements default magic methods and most derived objects don't actually reimplement them themselves. – tdelaney Jun 01 '21 at 18:25
3

There are already several good answers here, but none discuss the general concept of "truthy" and "falsy" expressions in Python.

In Python, truthy expressions are expression that return True when converted to bool, and falsy expressions are expressions that return False when converted to bool. (Ref: Trey Hunner's regular expression tutorial; I'm not affiliated with Hunner, I just love his tutorials.)

Falsy stuff:

What's important here is that 0, 0.0, [], None and False are all falsy.

When used in an if statement, they will fail the test, and they will pass the test in an if not statement.

Truthy stuff:

Non-zero numbers, non-empty lists, many objects (but read @tdelaney's answer for more details here), and True are all truthy, so they pass if and fail if not tests.

Equality tests

When you use equality tests, you're not asking about the truthiness of an expression, you're asking whether it is equal to the other thing you provide, which is much more restrictive than general truthiness or falsiness.

EDIT: Additional references

Here are more references on "Truthy" and "Falsy" values in Python:

joanis
  • 10,635
  • 14
  • 30
  • 40
2

In one case you are checking for equality with the value "False", on the other you are performing a boolean test on a variable. In Python, several variables pass the "if not x" test but only x = False passes "if x == False".

See example code:

x = [] # an empty list

if not x: print("Here!")
# x passes this test

if x == False: print("There!")
# x doesn't pass this test
Luiz F. Bianchi
  • 79
  • 1
  • 10
  • When I enter this code, it prints out "Here!" twice. That is very confusing though, how does it recognize 0 as a False? 0 is a number. – WillPak_Alt Jun 01 '21 at 18:10
  • The mistake was mine, that is very particular to Python (and I totally forgot about that lol) but 0 and False are the same thing for the compiler. Try running it now, I have fixed it. – Luiz F. Bianchi Jun 01 '21 at 18:11
  • As a general rule, boolean tests (if/ if not) will get you a lot farther than comparing to True or False. – Luiz F. Bianchi Jun 01 '21 at 18:13
  • Just one more thing, there is a book called "Learning Python" from O'Reilly which talks very thoroughly about these more conceptual things. I really recommend it. – Luiz F. Bianchi Jun 01 '21 at 19:09
0

Try it with x = None: not x would be True then and x == False would be False. Unlike with x = False when both of these are True. not statement also accounts for an empty value.

Toni Sredanović
  • 2,280
  • 1
  • 11
  • 13