[英]Ternary operator in Python raises TypeError when using * operator on empty list?
I want to print the contents of a list a
if len(a) > 0
, but otherwise I want to print -1
. 如果len(a) > 0
,我想打印列表a
的内容,否则我想打印-1
。 This seems to be pretty simple, but it's raising a TypeError
, stating that a
is an int, not a sequence, only when a
is an empty list: 这似乎很简单,但是它引发了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
Why is this the case? 为什么会这样呢?
According to the Python Documentation : 根据Python文档 :
The expression
x if C else y
first evaluates the condition,C
rather thanx
.x if C else y
首先计算条件C
而不是x
。 IfC
is true,x
is evaluated and its value is returned; 如果C
为true,则对x
求值并返回其值; otherwise,y
is evaluated and its value is returned. 否则,将评估y
并返回其值。
So *a
shouldn't be getting evaluated at all, and yet it's causing a TypeError? 所以*a
根本不应该得到评估,但是会导致TypeError?
I'm using Python 3.5 我正在使用Python 3.5
I'm not an expert, but looking at PEP 448 it looks like this *
syntax isn't part of the general expression syntax, but it's specific to function callsites (and other things like tuple and dictionary displays). 我不是专家,但是从PEP 448来看,它看起来像*
语法不是通用表达式语法的一部分,但是它特定于函数调用站点(以及其他类似元组和字典显示的内容)。 (It's a bit of a hack.) (有点hack。)
The PEP explicitly calls out some similar syntax that they've forbidden because they didn't know what it should do. PEP明确调用了一些他们已禁止的类似语法,因为他们不知道该怎么做。 It doesn't look like your code has been particularly considered though. 看起来您的代码似乎并未得到特别考虑。
Unbracketed comprehensions in function calls, such as f(x for x in it), are already valid. 函数调用中的方括号式理解(例如f(x中的x表示))已经有效。 These could be extended to: 这些可以扩展为:
f(*x for x in it) == f((*x for x in it)) f(* x用于其中的x)== f((* x用于其中的x))
f(**x for x in it) == f({**x for x in it}) f(** x表示x的值)== f({** x表示x的值})
However, it wasn't clear if this was the best behaviour or if it should unpack into the arguments of the call to f. 但是,尚不清楚这是否是最好的行为,还是应该将其分解为对f的调用的参数。 Since this is likely to be confusing and is of only very marginal utility, it is not included in this PEP. 由于这可能会造成混淆,并且仅具有很小的效用,因此它不包含在此PEP中。 Instead, these will throw a SyntaxError and comprehensions with explicit brackets should be used instead. 相反,它们将引发SyntaxError,而应使用带有括号的理解。
I think your code is effectively parsing as print(*(a if len(a) > 0 else -1))
, which is why you then get the error TypeError: print() argument after * must be a sequence, not int
. 我认为您的代码有效地解析为print(*(a if len(a) > 0 else -1))
,这就是为什么TypeError: print() argument after * must be a sequence, not int
错误TypeError: print() argument after * must be a sequence, not int
原因,它TypeError: print() argument after * must be a sequence, not int
。 By comparison, this works: 相比之下,这有效:
>>> print(*a if len(a) > 0 else ['nothing'])
nothing
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.