r=[True, False,True,False, False]
print([i for i in r if str(r[i])=="True"])
此代码给出以下意外结果: [假,假,假]
为什么这是行为?我希望: [True,True]
答案 0 :(得分:11)
i
是一个值为True
或False
的布尔值。如果您在r[i]
中将其用作索引,则会得到r[0]
或r[1]
,因为bool
是int
的子类。
您可以将其描绘为r[int(i)]
和int(True) == 1
,int(False) == 0
。
你的意思是:
print([i for i in range(len(r)) if str(r[i])=="True"])
其中i
是整数或:
print([i for i in r if str(i)=="True"])
其中i
是布尔值。
请注意,如果i
是布尔值,if str(i) == "True"
中几乎没有意义。更简洁的写作方式是:
print([i for i in r if i])
甚至使用filter内置函数:
it = filter(None, r)
print(list(it))
答案 1 :(得分:2)
您的意思是str(i)
。
使用原始代码
在第一次迭代时,i
为True
,而True
的整数值为1
,r[i]
将为{{1}这是假的。 r[1]
条件失败。
在第二次迭代中,if
为i
,而False
的整数值为False
,0
将为{{1}这是真的。 r[i]
条件成功,i(r[0]
)被添加到结果中。
答案 2 :(得分:2)
您以两种不同的方式使用i
:
r[i]
)[i for i in items]
r[i]
不是整数, i
通常会失败 - 列表只能通过整数索引。但是,布尔值是Python中的一个特例,bool
实际上是int
的子类:
>>> issubclass(bool, int)
True
>>> isinstance(True, int)
True
这就是为什么这甚至“有效”,并给你惊人的结果。
由于不需要在列表推导中使用列表索引,这就是你可能要编写的内容:
>>> print([i for i in r if str(i) == "True"])
[True, True]
另请注意,此处没有隐含的投射,与之前建议的其他答案不同:
Python不会这样做。它确实不“将r [i]翻译为r [int(i)]”。
让我们看一下字符串"1"
。如果你要求它,它会愉快地把它投射到int
:
>>> int("1")
1
但是,使用"1"
进行列表索引将永远不会起作用:
>>> lst = ['a', 'b', 'c']
>>> lst["1"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str
您的示例仅“有效”,因为bool
实际上 是int
的子类,而True
因此是整数,就Python而言。
答案 3 :(得分:2)
这可以为您提供所需的输出
r=[True, False,True,False, False]
print([i for i in r if str(i)=="True"])
我指的是数组中的各个元素。
答案 4 :(得分:1)
Jacques Gaudin是正确的,您正在使用布尔值进行索引。然而,更简单的代码版本是:
print([i for i in r if str(i)=="True"])
或者,当然:
print([i for i in r if i])