Python 中的三元运算符在空列表上使用 * 运算符时引发 TypeError?

Ternary operator in Python raises TypeError when using * operator on empty list?

如果 len(a) > 0,我想打印列表 a 的内容,否则我想打印 -1。这看起来很简单,但是它引发了一个TypeError,说明a是一个int,而不是一个序列,只有当a是一个空列表时:

>>> a = [2]
>>> print(*a if len(a) > 0 else -1)
2 # as expected
>>> a = []
>>> print(*a)

>>> # It has no trouble evaluating *a when a is empty
... ### HERE IS THE ERROR:
...
>>> print(*a if len(a) > 0 else -1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int
>>> ### But this works fine:
...
>>> if len(a) > 0:
...     print(*a)
... else:
...     print(-1)
...
-1

为什么会这样?

根据 Python Documentation:

The expression x if C else y first evaluates the condition, C rather than x. If C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.

所以 *a 根本不应该被评估,但它导致了 TypeError?

我正在使用 Python 3.5

我不是专家,但看看 PEP 448 看起来这个 * 语法不是通用表达式语法的一部分,但它特定于函数调用点(和其他东西)像元组和字典显示)。 (这有点骇人听闻。)

PEP 明确指出了一些他们禁止的类似语法,因为他们不知道它应该做什么。不过,您的代码似乎并未得到特别考虑。

Unbracketed comprehensions in function calls, such as f(x for x in it), are already valid. These could be extended to:

f(*x for x in it) == f((*x for x in it))

f(**x for x in it) == f({**x for x in it})

However, it wasn't clear if this was the best behaviour or if it should unpack into the arguments of the call to f. Since this is likely to be confusing and is of only very marginal utility, it is not included in this PEP. Instead, these will throw a SyntaxError and comprehensions with explicit brackets should be used instead.

我认为您的代码有效地解析为 print(*(a if len(a) > 0 else -1)),这就是为什么您会收到错误 TypeError: print() argument after * must be a sequence, not int。相比之下,这有效:

>>> print(*a if len(a) > 0 else ['nothing'])
nothing