8

I came across a strange behaviour of python comparing a string with True/False.

I thought that python would print in the following:

if "Test" == True:
    print("Hello1")

but it does not. So I wrote some Test cases and I do not understand some of them.

if "Test" == True:
    print("Hello1")

if "Test" == False:
    print("Hello2")

#This I understand
if bool("Test") == True:
    print("Hello3")

#This I understand too    
if bool("") == False:
    print("Hello4")

if "Test":
    print("Hello5")

Output

>> Hello3
>> Hello4
>> Hello5

So I do not understand:

  • If Hello1 is not printed why is not Hello2 either?
  • Why does Hello5 get printed, is the cast to bool("Test") made implicit?

2 Answers 2

7

In the first two comparisons, you are checking whether the string "Test" has the same value as the object True or False. This is a value comparison.

If they have a different type, the comparison will return False. You can see this also when comparing lists, numbers etc.: [1]==1 (false), (1,)==[1] (false).

In the third and fourth comparisons, you are still doing a value comparison, but since both sides are of the same type (boolean), it will compare the values.

Hello5 is printed because it is not the null string "". You can see this by trying "Test" != None, which returns True.

While it is a comparison to None when it comes to most classes(None is Python's null value), Python's standard data types are compared to their "null" value, which are:

  • The empty string "" for strings,
  • [] for lists (similary () for tuples, {} for dictionaries),
  • 0 for ints and floats,

just like a boolean comparison. Therefore it is not wrong to think of if expression as an implicit cast to if bool(expression).

What is going on under the hood is the evaluation of the __non-zero__(python2.x) or __bool__(python3.x) method of the class.

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

3 Comments

If you improve your answer to contain the object comparison too it is actually better then the on of user762353. An anwser should always stand on its own.
@M.T The first four comparison are not comparing objects, but values. To compare objects (or in other words, identity) would be "Test" is True not "Test" == True. I think this is what you mean, but your verbiage is ambiguous. Please clarify your answer for future users.
@M.T Also, another correction: None is not (strictly speaking or otherwise) a class; it is a singleton. In other words, it in an instance of class NoneType that has only one allowed instance: None. You should remove the statement that it is a class from your answer as it is false information. Other than the things I mentioned, this is a very good answer.
2

In the case of Hello1, Hello2 and Hello5 there is an object comparison and not boolean comparions.

That means that
the string-object "Test" is not the same as object True ("Hello1")
the string object "Test" is not the same as object False("Hello2")
but the string object "Test" is not None ("Hello5")

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.