Using break in an inline if statement in a loop causes a syntax error

I tried to do this

while True:
    break if input() == 'q' else input()

      

This throws a syntax error

    break if input() == 'q' else input()
           ^
SyntaxError: invalid syntax

      

I know there are other ways to do this, but I was wondering why it didn't work.

Thank!

+3


source to share


5 answers


This is called a conditional expression, and the Grammer for this is defined as this

conditional_expression ::=  or_test ["if" or_test "else" expression]

      

And is or_test

defined as follows

or_test  ::=  and_test | or_test "or" and_test

      

And is and_test

defined as follows

and_test ::=  not_test | and_test "and" not_test

      

and is not_test

defined as follows

not_test ::=  comparison | "not" not_test

      

and is comparison

defined as follows

comparison    ::=  or_expr ( comp_operator or_expr )*

      

and is comp_operator

defined as follows:

comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"

      

and is or_expr

defined as follows:

or_expr  ::=  xor_expr | or_expr "|" xor_expr

      

and is xor_expr

defined as follows:

xor_expr ::=  and_expr | xor_expr "^" and_expr

      

and is and_expr

defined as follows:



and_expr ::=  shift_expr | and_expr "&" shift_expr

      

and is shift_expr

defined as follows:

shift_expr ::=  a_expr | shift_expr ( "<<" | ">>" ) a_expr

      

and is a_expr

defined as follows

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

      

and is m_expr

defined as follows:

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

      

and is u_expr

defined as follows:

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

      

and is power

defined as follows:

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

      

and is primary

defined as follows:

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

      

And there is no instruction break

in the grammar, so it fails with a compile-time error.

Quote from docs,

The expression x if C else y

first evaluates the condition C

, and not x

. If C

true, x

evaluates and returns its value; otherwise, it y

evaluates and returns its value.

So, x

and y

should be something that can be evaluated, but break

is a control flow operator that cannot be evaluated.

+3


source


A conditional expression should be used with expressions, not with operators.

And, the code calls input

twice to login q

. Is this what you mean?



while True:
    in_ = input()
    if in_ == 'q':
        break
    # Do something with in_

      

+1


source


This syntax cannot be used like this. The whole thing <something> if <condition> else <other thing>

is an expression that evaluates to some specific value, that is, something assigned to a variable. The idea is not to put logic in <something>

and <other thing>

. You will have to stick with something more traditional:

while True:
  if input() == 'q':
    break

      

+1


source


The inline if statement - also called conditional assignment - is python equivalent to the tenary statement in other languages. Thus, it is used to assign a value to a variable based on the boolean value of an expression, for example:

greeting = 'Mrs.' if person.female else 'Mr.'

      

Obviously, both possible values ​​must indeed be values. This is true for all literals (1, 'string', ...), variables, and function calls, but not for statements such as break .

I hope this explains why this is a syntax error.

+1


source


If you want to keep typing input until the user is logged in "q"

, you can use iter

:

for x in iter(input,"q"):
    print (x)

      

Or simply:

while input() != "q":

      

0


source







All Articles