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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to