简体   繁体   中英

Making two conditional/loop statements with a simple statement work in one python line

This is a python grammar question.

Why is it not possible to run if test: for list: one-statement in one line in python? eg:

a=1
b=[1, 2]
if a: for x in b: print(x)
  File "<ipython-input-52-8abcd450fc7a>", line 3
    if a: for x in b: print(x)
            ^
SyntaxError: invalid syntax

I understand that it'd be an issue with indentation should there be 2+ statements to follow, but one statement creates no ambiguity. Am I wrong?

Splitting the one-liner works, as it disambiguates it:

a=1
b=[1, 2]
if a: 
    for x in b: print(x)
1
2

Looking at the python grammar we have:

if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

Won't something like the following change to if_stmt allow for such simple nested statements in one line?

simple_for_stmt: 'for' exprlist 'in' testlist ':' simple_stmt
if_stmt: 'if' test ':' (suite ('elif' test ':' suite)* ['else' ':' suite] | simple_for_stmt) 
                       ^                                                  ^^^^^^^^^^^^^^^^^^

Besides the change to if_stmt I defined a new token simple_for_stmt . Of course this is just for the for statement, but it could be adjusted for while and others.

I understand, of course, that perhaps keeping things simple is the best approach in python land - add the damn new line!

note: this is not a help-me-make-my-code-run question. The code example is just to demonstrate the issue, it doesn't need to be fixed/improved. So please refrain from suggesting how the example code can be rewritten in a different way. Thank you.

I'm using python 3.6.6.

I think the the solution you propose is a hint as to why it was never implemented. The change would add a lot of complexity to the grammar with very little real benefit. A few simple statements could be shoe-horned into a single line, but the change would create a number of confusing edge cases.

The Python docs explicitly say that

if test1: if test2: print(x)

must be illegal because it would not be clear which if a following else clause belonged to. (Obviously, an arbitrary decision could be implemented, but that would still cause confusion for readers of the code.) This argument also applies to for statements (and other compound statements) because in Python a for statement can also have an else clause.

The problem is not the if statement, it is the for statement. What you want to want can be do as follows

a = True
b = [1,2,3]
if a: [print(x) for x in b]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM