2015-05-04 18 views
2

我试图用all()但它不是为我工作:如何使用all()内置函数?

>>> names = ["Rhonda", "Ryan", "Red Rackham", "Paul"] 
>>> all([name for name in names if name[0] == "R"]) 
True 
>>> 

我想检查是否所有的名字与"R"开始,即使我添加"Paul"namesall()仍返回True。我如何解决这个问题,以便all()返回False,直到"Paul"被删除?

+0

什么是你期待? – ZdaR

+1

另外:字符串有'startswith'方法,所以'name.startswith(“R”)'也可以。 – DSM

+1

'if all(c [0] ==“R”for c in name):' –

回答

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而不是列表理解。通过列表理解,代码需要在确定结果之前测试所有字符串。然而,新代码只会根据需要进行检查。

+0

谢谢!我正试着把一个*评估*列表理解放在'all' :) – user1823

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 
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 
0
names = ["Rhonda", "Ryan", "Red Rackham", "Paul"] 
if all(c[0] == "R" for c in names): 
    print "ALL MATCH" 

演示:

http://ideone.com/KenqJl

相关问题