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