pythonbooleanbitwise-operatorslogical-operatorstruthiness

Python if statements and truth value testing for non compsci background


This aims to be a self answered question after a few hours of digging, I found this thought process may prove useful to others who also may not have come from a formal compsci background.

This all started from confusion over why one particular if statement was being entered.

>>>if (2 & 2):
...    print("true")
true

Why was this if statement being entered?


Solution

  • My previous use of if statements were all quite straightforward, so I took it for granted and with the understanding that only a boolean True would result in the entering of an if statement. What constitutes a boolean True, was not so obvious to me after running into this if statement. This is surely obvious to those with a compsci background, but I never really dug into how if statements determined if the argument was a boolean True or not. For example, if (5 > 2) --> True just makes sense to anyone with at least an elementary-school math background, so I took it for granted. On the contrary, if (2) --> True, does not seem too obvious to a non compsci specialist.

    For example

    >>>2 & 2
    2
    >>> 2 == True
    False
    >>>if (2):
    ...    print("true")
    true
    

    Why was the if statement entered despite 2 & 2 evaluating to an int value of 2? Why was the if statement entered if given the int value 2 even though 2 itself is not == True? This was the first I had seen this type of behavior and it lead me to understand from various other stack overflow questions that the if statement is not evaluating if the int value of 2 == True, but instead evaluating bool(2) == True, which is in fact True.

    Again, if you come from a comp sci background, I'm sure this is all very obvious, but even the idea of bool(2) and "truth value testing" as a phrase was new to me, so adding this on to the binary logical operators caused me a fair bit of confusion at first. For example:

    >>>2 & 4
    0
    >>>if (2 & 4):
    ...    print("true")
    >>>bin(2 & 4)
    '0b0'
    >>>if ('0b0'):
    ...    print("true")
    true
    >>>if (0b0):
    ...    print("true")
    >>>bool(0)
    False
    >>>bool(0b0)
    False
    >>>bool(b'0')
    True
    >>>bool(bin(0))
    True
    

    At first, with the misunderstanding that the if statements were evaluating if the argument == True, the above examples seemed quite illogical, as I thought a binary 1 should result in True and binary 0 should result in False. I had no idea why integer values above 1, in either int or binary form should return True.

    After reading through the python docs for Truth Value Testing I see a few examples of objects that are considered false. Here, and rather obviously, it makes sense why bool(0) and bool(0b0) returns False. The opposite though, for bool(b'0') and bool(bin(0)), where this seems to return True. Why is this? Because bin() returns a string representation of the number, as is b'0' (a string) not an actual binary value (like 0b0), and since these strings are not empty strings, but rather filled with the characters representing zero, it evaluates to True (See third bullet point of Truth Value Testing).

    I gave a few examples of non-obvious (to me) truth evaluation tests, and why they do actually make logical sense. Hope this helps others who may be mystified by the seemingly (to me) lesser common uses of the if statement.