Arithmetic with Boolean values

MRAB python at mrabarnett.plus.com
Sat Aug 11 20:36:45 EDT 2012


On 11/08/2012 23:30, John Ladasky wrote:
> I have gotten used to switching back and forth between Boolean algebra and numerical values.  Python generally makes this quite easy.  I just found a case that surprises me.
>
> Here is what I want to accomplish:  I want to process a list.  If the length of the list L is odd, I want to process it once.  If len(L) is even, I want to process it twice.  I thought I would set up a loop as follows:
>
> for x in range(1 + not(len(L) % 2)):
>      # Do stuff
>
> This provoked a SyntaxError.  I investigated this further with my interpreter (ipython).
>
> In [1]: L = range(5)
>
> In [2]: L
> Out[2]: [0, 1, 2, 3, 4]
>
> In [3]: len(L)
> Out[3]: 5
>
> In [4]: len(L) % 2
> Out[4]: 1
>
> In [5]: not(1)
> Out[5]: False
>
> In [6]: not(len(L) % 2)
> Out[6]: False
>
> In [7]: 1 + not(len(L) % 2)
> ------------------------------------------------------------
>     File "<ipython console>", line 1
>       1 + not(len(L) % 2)
>             ^
> SyntaxError: invalid syntax
>
> So as you can see, every thing is working fine until I attempt to add 1 and False.  However:
>
> In [8]: 0 == False
> Out[8]: True
>
> In [9]: 1 == True
> Out[9]: True
>
> So, 0 and False do pass an equivalency test, as do 1 and True.  Furthermore:
>
> In [10]: 1 + (len(L) % 2 == 0)
> Out[10]: 1
>
> Why is using a logical "not" function, as shown in [7], returning a different result than the test for equivalency as shown in [10]?
>
> Of course I'm just going to use [10] in my program, but I'd like to understand the reason that I'm getting that SyntaxError.  I've been reading Python style guides, and at least one of them states a preference for using the "not" syntax over the "== 0" syntax.
>
> I'm using Python 2.7, in case it matters.
>
I think the problem is that "not" isn't a function as such - it doesn't 
require parentheses, for example.

The relevant syntax rules are:

a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr

m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/"
u_expr | m_expr "%" u_expr

u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr

power ::= primary ["**" u_expr]

primary ::= atom | attributeref | subscription | slicing | call

atom ::= identifier | literal | enclosure

enclosure ::= parenth_form | list_display | dict_display | set_display | 
generator_expression | yield_atom

call ::= primary "(" [argument_list [","] | comprehension] ")"

In order for your code to work I think we would need to have something 
like this:

primary ::= atom | attributeref | subscription | slicing | call | not_expr

not_expr ::= "not" parenth_form




More information about the Python-list mailing list