minerals
minerals

Reputation: 1315

Explain string boolean test result

I have this code:

>>> char = 'A'
>>> 'A' == char
True
>>> ('A' or 'B') == char
True

Why does this not equal True?

>>> ('B' or 'A') == char
False

Upvotes: 3

Views: 128

Answers (3)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250951

the comparisons you're doing actually compares the boolean values of 'A' and 'B'.

so : ('A' or 'B') is actually (bool('A') or bool('B'), as it's a or condition and as bool('A') is True in first case so it compares 'A'==char , and in second case as bool('B') is True so it compares 'B'==char( which is False)

In [114]: False or True
Out[114]: True

In [115]: True or False
Out[115]: True

In [116]: True or True
Out[116]: True

In [117]: bool('A')
Out[117]: True

In [118]: bool('B')
Out[118]: True

this is how it happens in background:\

In [104]: def func():
    char="A"
    return ('A' or 'B')==char
   .....: 

In [107]: def func1():
    char="A"
    return ("B" or "A")==char
   .....: 

In [110]: dis.dis(func)
  2           0 LOAD_CONST               1 ('A')  
              3 STORE_FAST               0 (char)

  3           6 LOAD_CONST               1 ('A')   #loads 'A'
              9 JUMP_IF_TRUE             4 (to 16)  # if 'A' is True then go to 16
                                                    # As 'A' is not a falsy value so it                                                                                                         
                                                     goes to  16
             12 POP_TOP                  
             13 LOAD_CONST               2 ('B')
        >>   16 LOAD_FAST                0 (char)  #load char , i.e 'A'
             19 COMPARE_OP               2 (==)    #compare 'A'=='A' , i,e True
             22 RETURN_VALUE        

In [111]: dis.dis(func1)
  2           0 LOAD_CONST               1 ('A')
              3 STORE_FAST               0 (char)

  3           6 LOAD_CONST               2 ('B')      #load 'B', it's a true value
                                                      # so go to 16
              9 JUMP_IF_TRUE             4 (to 16)
             12 POP_TOP             
             13 LOAD_CONST               1 ('A')
        >>   16 LOAD_FAST                0 (char)     #load chr ,i.e 'A'
             19 COMPARE_OP               2 (==)       #'B'=='A' , False
             22 RETURN_VALUE        

Upvotes: 2

Brian Cain
Brian Cain

Reputation: 14619

The difference is how those expressions evaluate:

In [1]: 'A' or 'B'
Out[1]: 'A'

In [3]: 'B' or 'A'
Out[3]: 'B'

...therefore, 'B' or 'A' shouldn't equal char in your case.

For details on how or should work, consult the "Boolean operations" section of the python docs:

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

That ordering described above is critical and includes a concept called "lazy evaluation."

Upvotes: 3

Collin
Collin

Reputation: 12287

Your expressions are not doing what you expect.

'A' or 'B'

This actually evaluates to 'A', try it out in the interpreter!

When you say

('A' or 'B') == char

The interpreter is actually doing these steps:

('A' or 'B') == char
('A') == char
True

But when you do

('B' or 'A') == char

The interpreter does this:

('B' or 'A') == char
('B') == char
False

What you probably wanted was:

'A' == char or 'B' == char
True

Upvotes: 6

Related Questions