这就是我所理解的:
>>> ['False', 'True'][True]
'True'
>>> ['False', 'True'][False]
'False'
>>>
现在我尝试了以下代码片段并获得了TypeError:
>>> c = 'a'
>>> ['Invalid', ['x']*c][type(c) is int]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>>
所以,当我将['x'] * c更改为False时,它会起作用:
>>> ['Invalid', 'False'][type(c) is int]
'Invalid'
>>>
并且:我将c更改为2:
>>> c = 2
>>> ['Invalid', ['x']*c][type(c) is int]
['x', 'x']
>>>
注意:我知道 - 否则可以做到,但这不是我的观点。
答案 0 :(得分:4)
['Invalid', ['x']*c]
即使您只获得0
个元素,也必须生成整个列表。构建列表时,如果c
是字符串,则Python无法评估['x']*c
。这就是它失败的原因。
答案 1 :(得分:2)
它不是三元运算符:没有短路评估。
在表达式['Invalid', ['x']*c][type(c) is int]
中,无论以下索引如何填充列表对象项,都会首先计算['Invalid', ['x']*c]
。
你最好使用条件表达式:
['x'] * c if isinstance(c, int) else 'Invalid'
答案 2 :(得分:2)
问题是这不是一个真正的三元运算符;它是一个列表,在查看下标之前将对整个列表进行评估。
有可能,你真正想要的是:
['x']*c if type(c) == int else 'Invalid'
在某些情况下,列表黑客“有效”的原因是True
和False
强制转换为1
和0
。但是你正在做的是构建列表(包括真路径和假路径),然后使用下标选择列表中的元素。
如果我们删除下标并写下列表,原始想法失败的原因可能更清楚:
c = 'a'
choices = ['Invalid', ['x']*c]
很明显为什么choices
会抛出TypeError
,对吧?所以你不能下标它,因为它永远不会完成评估。
答案 3 :(得分:1)
我不认为在尝试对其进行有条件操作之前构建有效列表的观点正在被问题的海报所理解。 ['X'] * c,当c是一个字符时,将失败。