我注意到在三元表达式中解压缩多个值时存在一个奇怪的问题。首先,一个说明语法的 MWE,其目的是解压缩右侧的元组,并将其中的列表分配给左侧的第一个名称,将数字分配给第二个名称。
condition = False
a, b = [1, 2], 3 if not condition else None, None # ValueError: too many values to unpack
def foo():
return [1, 2], 3
([1, 2], 3) == foo() # True
a, b = foo() # works as expected: a = [1, 2] and b = 3
a, b = foo() if not condition else None, None # now a = ([1, 2], 3) and b is None
我的问题是理解这里语法背后的基本原理。如果condition
的计算结果为 false,为什么三元表达式的最后一部分,即else
子句,会被计算出来呢?Python 是否将第二个None
分配给b
?这对我来说毫无意义,但我看不出还有什么 a( 没有引发 ValueError 来告诉我解包根本没有工作(如果我的语法以某种方式迫使 Python 将整个元组视为单个实体而不是解压缩它(和 b( 仍然为b
赋值。显而易见的下一个测试:
a, b = foo() if not condition else None, 'test' # Now a = ([1, 2], 3) and b = 'test'
a, b = (lambda x: [[1, 2], 3])('blah') if not condition else None, 'test' # Same result with a lambda function.
因此,似乎正在评估 else 子句。为什么会这样?有没有一种优雅的重写方法,允许我在这样的三元表达式中调用函数,除了明显且可以说更笨拙的函数
if not condition:
a, b = foo()
else:
a, b = None, None
这只是优先级。Python 将其解析为:
a, b = (foo() if not condition else None), None
对于预期的结果,您需要在"无"两边添加括号:
a, b = foo() if not condition else (None, None)
这里发生的事情是,python 将你的三元表达式作为第一个要解压缩的项目,, None
作为第二个项目。括号相同:
a, b = (foo() if not condition else None), None
这可以通过执行以下操作来缓解:
a, b = foo() if not condition else (None, None)
这将为您提供正确的结果:
>>> a, b = foo() if not condition else (None, None)
>>> a, b
([1, 2], 3)