我正在尝试使用all()
,但这对我不起作用:
>>> names = ["Rhonda", "Ryan", "Red Rackham", "Paul"]
>>> all([name for name in names if name[0] == "R"])
True
>>>
我正在尝试检查所有名称是否都以"R"
开头,即使我将"Paul"
添加到names
,all()
仍会返回True
。如何解决此问题,以便all()
在False
被移除之前返回"Paul"
?
答案 0 :(得分:8)
你误解了all
的工作原理。来自docs:
all(iterable)
如果
True
的所有元素都为真(或者如果是),则返回iterable
iterable
是空的。
在您的代码中,您首先将所有以R
开头的名称收集到列表中,然后将此列表传递给all
。执行此操作将始终返回True
,因为非空字符串的计算结果为True
。
相反,你应该写:
all(name[0] == "R" for name in names)
这会将可迭代的布尔值传递给all
。如果所有这些都是True
,则函数将返回True
;否则,它将返回False
。
作为一个额外的奖励,现在结果将被懒惰地计算,因为我们使用generator expression而不是列表理解。使用列表理解,在确定结果之前测试所有字符串所需的代码。但是,新代码只会根据需要进行检查。
答案 1 :(得分:0)
names = ["Rhonda", "Ryan", "Red Rackham", "Paul"]
print all(map(lambda name: name[0] == "R", names))
# prints False
names = ["Rhonda", "Ryan", "Red Rackham"]
print all(map(lambda name: name[0] == "R", names))
# prints True
答案 2 :(得分:0)
你得到错误结果的原因是因为你已经通过应用所需条件使用列表理解创建了一个新列表,所以如果我们做了一点细分那么:
>>> print [name for name in names if name[0] == "R"]
>>> ['Rhonda', 'Ryan', 'Red Rackham']
>>> print all(['Rhonda', 'Ryan', 'Red Rackham'])
>>> True
所以正确的方法可能是:
names = ["Rhonda", "Ryan", "Red Rackham", "Paul"]
res = all(map(lambda x : x[0]=="R", names))
# map() returns: [True, True, True, False]
# all([True, True, True, False]) == False
print res
答案 3 :(得分:0)
names = ["Rhonda", "Ryan", "Red Rackham", "Paul"]
if all(c[0] == "R" for c in names):
print "ALL MATCH"
演示: