2

当测试多个条件是否为真时,是and语句还是all()更快?例如:

if '1234'.isdigit() and '4567'.isdigit() and '7890'.isdigit(): 
    print "All are digits!"

或者

if all(['1234'.isdigit(), '4567'.isdigit(), '7890'.isdigit()]): 
    print "All are digits!"

谢谢!

4

3 回答 3

11

ands 更快,没有列表创建和函数调用。

In [10]: %timeit '1234'.isdigit() and '4567'.isdigit() and '7890'.isdigit()
1000000 loops, best of 3: 186 ns per loop

In [11]: %timeit all(['1234'.isdigit(), '4567'.isdigit(), '7890'.isdigit()])
1000000 loops, best of 3: 323 ns per loop

 

ands 甚至不会不必要地评估事物:

In [1]: def x():
   ...:     print 'call'
   ...:     return False
   ...:

In [2]: x() and x()
call
Out[2]: False

In [3]: all([x(), x()])
call
call
Out[3]: False
于 2013-02-28T21:18:50.720 回答
5

第二个评估所有条件,将这些布尔值放入列表中,然后检查它们是否全部为真。

另一方面,第一个只是一个接一个地检查它们并在第一个错误条件(如果有的话)处停止。正如 Pavel 的回答所示,第一个肯定更快。

您还可以使用发电机,它可以让all短路:

all(str.isdigit(s) for s in your_strings)
于 2013-02-28T21:20:54.217 回答
2

如果您真的想要处理 3 个静态值的最快方法,并且几十纳秒的差异在您的代码中实际上很重要:

if True:
    print "All are digits!"

或者,甚至更快:

print "All are digits!"

在任何情况下,性能最重要,您将拥有大量和/或动态的值集,您根本无法使用 来做到这一点and,除非创建一个显式for循环:

value = True
for s in strings:
    value = value and s.isdigit()
    if not value:
        break
if value:
    print "All are digits!"

你可以立即看到它and根本没有帮助:

for s in strings:
    if not s.isdigit():
        break
else:
    print "All are digits!"

但是如果你想用 来更快地做事情all,你可以使用生成器表达式(或map/imap调用)而不是列表推导式,它同样快速且易读,具有大的动态序列和小的静态序列:

if all((x.isdigit() for x in ('1234', '4567', '7890')):
    print "All are digits!"

if all((x.isdigit() for x in strings):
    print "All are digits!"

如果序列非常大,并且某些值可能是假的,这将比任何涉及构建list所有真/假值的方法都要快得多。

于 2013-02-28T21:25:01.453 回答