是否有一种优雅,可读的方法来检查可迭代it
中的所有元素是否解析为True
(您可能会认为所有值都是布尔值,尽管这与我的问题无关)?我提出了:
any(it) and not reduce(lambda x, y: x and y, it)
但是我认为减少使得理解有些混乱,加上我觉得它不起作用:
In [1]: a=[True, True, False]
In [7]: any(a) and not reduce(lambda x, y: x and y, a)
Out[7]: True
有更可读的方法吗?
更新:我在上面的表达式中意识到错误。 reduce()需要停止,当它看到True而不是继续。
答案 0 :(得分:6)
您的标题不同意您的问题正文,但我会回答标题。
您可以sum
布尔值。检查它是否等于1(或您喜欢的任何值):
>>> a = [True, True, False]
>>> sum(a)
2
>>> b = ['hey', '', 'a string']
>>> sum(map(bool,b))
2
答案 1 :(得分:5)
您可以使用count
执行此操作:
>>> a=[True, True, False]
>>> if a.count(True) == 1:
... print 'Hello'
... else:
... print 'Sorry'
Sorry
>>> [True, False].count(True) == 1
True
>>> [True, True, False].count(True) == 1
False
>>> [True, True, False].count(False) == 1
True
答案 2 :(得分:0)
所以,这个的一般格式是这样的:
test = [True, True, False]
if len([x for x in test if x]) == 1:
# Do something
当然,以上只是测试x
是否为布尔True
,但你可以在那里进行任何比较。
你可能会说,但效率不高吗?不是真的,如果你真的想要N个项目 - 无论如何都要检查它们,看看是否还有其他True
潜伏在那里。
对于'N或更多'项目的情况,您可以使用生成器(ab)来执行此操作:
from itertools import islice
result = True
g = (x for x in test if x)
if len(list(islice(g, 2))) == 2:
# do something
这是一个捷径,因为它会在看到物品数量后立即停止,而不会越走越远。如果您想使用此表单进行精确计数,则它比列表表单有一个小优势:
if len(list(islice(g, 2))) == 2 and not any(g):
# do something
为什么这有一个小优势?在通过案例中,我们仍然需要查看其他所有项目,以确保列表中只有2 Trues
。但是在失败的情况下,只要我们看到另一个True
,any
就会快捷方式,您将无法浏览列表的其余部分。