Odd Python parsing?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
pythoncoder
Posts: 3699
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Odd Python parsing?

Post by pythoncoder » Wed Aug 14, 2019 5:22 am

Apologies for raising something which isn't MicroPython specific. The following is a rare instance of a simple piece of Python code whose behaviour surprised me. I wondered what others think. MicroPython and cPython behave similarly. Consider:

Code: Select all

def foo(bar):
    print((1, 2) if bar else 3, 4)
If passed False it produces 3, 4 which was my expectation. If passed True it produces (1, 2) 4 which I find bizarre. The parser's interpretation of the comma between 3, 4 evidently depends on the state of bar. Is this really to be expected?

The workround is simply to make 3, 4 a tuple.
Peter Hinch

User avatar
jimmo
Posts: 883
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: Odd Python parsing?

Post by jimmo » Wed Aug 14, 2019 5:45 am

The rules work out such that the expression is equivalent to:

Code: Select all

print(((1, 2,) if bar else 3), 4)
So you either get

Code: Select all

print((1, 2,), 4) # (1, 2) 4
or
print(3, 4) # 3 4
pythoncoder wrote:
Wed Aug 14, 2019 5:22 am
The parser's interpretation of the comma between 3, 4 evidently depends on the state of bar. Is this really to be expected?
As far as I can tell, it's interpreted as the argument separator for the call to print() in both cases?

User avatar
Roberthh
Posts: 1735
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Odd Python parsing?

Post by Roberthh » Wed Aug 14, 2019 5:59 am

Peter, why should that be bizarre. In your example, print has two parameters:
(1, 2) if bar else 3
4
So it will print, depending on bar, (1, 2) or 3, and it will always print 4. So this is more an example on how ternary expression can create hard-to-read code. Although, I like to use them, but most of the time in simple assignments.

User avatar
pythoncoder
Posts: 3699
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Odd Python parsing?

Post by pythoncoder » Wed Aug 14, 2019 7:44 am

It isn't related to the print statement. You get the same outcome without it:

Code: Select all

>>> bar = False
>>> z = (1, 2) if bar else 3, 4
>>> z
(3, 4)
>>> bar = True
>>> z = (1, 2) if bar else 3, 4
>>> z
((1, 2), 4)
>>> 
Peter Hinch

User avatar
jimmo
Posts: 883
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: Odd Python parsing?

Post by jimmo » Wed Aug 14, 2019 7:53 am

pythoncoder wrote:
Wed Aug 14, 2019 7:44 am
It isn't related to the print statement.
Right, in this case it's the separator for a tuple expression. But the parser still handles the comma the same way, regardless of the value of bar. It's the same as:

Code: Select all

>>> bar = False
>>> x = (1, 2) if bar else 3
>>> z = x, 4
>>> z
(3, 4)
>>> bar = True
>>> x = (1, 2) if bar else 3
>>> z = x, 4
>>> z
((1, 2), 4)
>>> 

User avatar
pythoncoder
Posts: 3699
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Odd Python parsing?

Post by pythoncoder » Wed Aug 14, 2019 11:54 am

jimmo wrote:
Wed Aug 14, 2019 7:53 am
...the parser still handles the comma the same way...
Right, got it! Thanks.
Peter Hinch

Post Reply