在循环中使用内联if语句的break会导致语法错误。

3

我正在尝试这个

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

这会导致语法错误。
    break if input() == 'q' else input()
           ^
SyntaxError: invalid syntax

我知道有其他方法可以做到这一点,但我想知道为什么这种方法不起作用。

谢谢!


这段代码的总体目的是什么? - matsjoyce
人们想要这样做,这正是为什么Guido长期抵制添加条件表达式的原因。不要试图在Python中编写惯用的Perl代码。 - Wooble
5个回答

3
这被称为条件表达式,其语法定义如
conditional_expression ::=  or_test ["if" or_test "else" expression]

or_test 的定义如下

or_test  ::=  and_test | or_test "or" and_test

and_test的定义如下:

and_test ::=  not_test | and_test "and" not_test

not_test的定义如下:

not_test ::=  comparison | "not" not_test

而且比较是这样定义的

comparison    ::=  or_expr ( comp_operator or_expr )*

而且comp_operator的定义如下所示

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

or_expr的定义如下:

or_expr  ::=  xor_expr | or_expr "|" xor_expr

xor_expr 的定义如下:

xor_expr ::=  and_expr | xor_expr "^" and_expr

and_expr定义如下:

and_expr ::=  shift_expr | and_expr "&" shift_expr

shift_expr 的定义如下

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

a_expr 的定义如下:

a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_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 是这样定义的

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

power的定义如下:

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

并且primary是这样定义的

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

没有任何地方允许在语法中使用break语句,这就是为什么它会因为编译时错误而失败的原因。
引用文档中的话:
表达式x if C else y首先评估条件C而不是x。如果C为真,则评估x并返回其值;否则,评估y并返回其值。
因此,xy应该是可以被评估的内容,但是break是控制流语句,无法被评估。

为了_某事_的爱,请将您的定义折叠成一个代码块。 - Xan

1

内联if语句 - 也称为条件赋值 - 是Python中类似于其他语言中的三元运算符。因此,它用于根据表达式的布尔值将值分配给变量,例如:

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

很明显,两个可能的值必须实际上是值。这对于所有字面量(1、'string'等)、变量和函数调用都是正确的,但对于像break这样的语句则不是。

我希望这解释了为什么这是一个语法错误。


1

条件表达式应该与表达式一起使用,而不是与语句一起使用。

此外,代码对于非q输入调用了两次input。这是你的意思吗?

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

我理解可以这样做。但我不明白为什么我不能在内联if语句中使用break - Kidus
1
@DJK,break不是表达式,而是语句。 - falsetru

1
那种语法不能这样使用。整个 <something> if <condition> else <other thing> 的东西是一个表达式,它会计算出某个特定的值,也就是说,可以将其分配给变量。这个想法不是把逻辑放在 <something><other thing> 中。你必须坚持使用更传统的方法:
while True:
  if input() == 'q':
    break

0
如果你想一直接收输入,直到用户输入了"q",你可以使用iter:
for x in iter(input,"q"):
    print (x)

或者只是:

while input() != "q":

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接