(no) fast boolean evaluation ? missing NOT

Diez B. Roggisch deets at nospam.web.de
Fri Aug 3 13:09:03 CEST 2007


Stef Mientki schrieb:
> John Machin wrote:
>> On Aug 3, 8:55 am, Ian Clark <icl... at mail.ewu.edu> wrote:
>>> Stef Mientki wrote:
>>>> hello,
>>>> I discovered that boolean evaluation in Python is done "fast"
>>>> (as soon as the condition is ok, the rest of the expression is 
>>>> ignored).
>>>> Is this standard behavior or is there a compiler switch to turn it 
>>>> on/off ?
>>>> thanks,
>>>> Stef Mientki
>>> It's called short circuit evaluation and as far as I know it's standard
>>> in most all languages. This only occurs if a conditional evaluates to
>>> True and the only other operators that still need to be evaluated are
>>> 'or's or the condition evaluates to False and all the other operators
>>> are 'and's. The reason is those other operators will never change the
>>> outcome: True or'd with any number of False's will still be True and
>>> False and'ed to any number of Trues will still be False.
>>>
>>> My question would be why would you *not* want this?
>>>
>>>
>>
>> Why? Perhaps under some compound condition like this:
>>
>> (you_are_confused and/or
>> function_returns_bool_but_has__side_effects())
>>
> 
> Thanks guys,
> Yes this is exactly what's going wrong ...
> 
> Sorry, my question missed the essential "NOT",
> here is an example, that behaves different in Delphi,
> (so I guess Delphi is not a real language ;-)
> 
> <Python>
> def Some_Function (const):
>     print 'Ive been here', const
>     return True
> 
> A = True
> 
> if A and Some_Function (4 ):
>     print 'I knew it was True'
> else:
>     print 'I''ll never print this'
> </Python>
> 
> <Output>
> Ive been here 4
> I knew it was True
> </Output
> 
> I was expected that the function would not be called,
> because A is True.
> 
> And I agree with Laurent that it should be better to write a clean code,
> so it doesn't matter whether you write in Python or in Delphi.
> 
> Gabriel: you pointed me to this page:
> The exact behavior is defined in the Language Reference 
> <http://docs.python.org/ref/Booleans.html>
> 
> <quote>
> or_test      ::=      and_test | or_test "or" and_test
> </quote
> 
> Can you imagine, while I'm not a programmer, just a human,
> that I don't understand one bit of this line.
> 
> So now I'm left with just one question:
> for bitwise operations I should use &, |, ^
> for boolean operations I should use and, or, xor
> but after doing some test I find strange effects:
>  >>> A = 4
>  >>> B = 5
>  >>> A and B
> 5
>  >>> A & B
> 4
>  >>> A or B
> 4
>  >>> A | B
> 5
> 
> So if I use the bitwise operation on integers,
>   "and" changes into (bitwise) "or" and vise versa.

No!!! Don't think that!

Choose different numbers, and you will see that.

The semantics for the and/or operators are spelled out like this 
(extra-verbose):


def and(a, b):
     if bool(a) == True:
        if bool(b) == True
           return b # because it holds True == bool(b)
     return a # because it holds Fals == bool(a)

def or(a, b):
     if bool(a) == True:
        return a
     return b


This could be considered unfortunate because it relies on the implicit 
boolean nature of certain values like "", 0, 1, {} and so forth - but 
it's the way it is.

However, this has _nothing_ to do with the bitwise operations! The work 
on the bits of integers, and because 5 and 4 are bitwise 0b101 and 
0x100, the

5 & 4 -> 4 == 0b100

and

5 | 4 -> 5 == 0x101

That's all!

If you need non-circuiting and/or, write functions and and or:

def and_(a, b):
     return a and b

def or_(a, b):
     return a or b

That will ensure argument evaluation.

Diez



More information about the Python-list mailing list