2012-11-07 54 views
2

要强制转换值以布尔值,我通常会做到以下几点:在哪里将``not not`而不是`bool()`布尔变为布尔值失败?

not not value 

这比使用bool更快。从timeit输出:

python -m timeit '[bool(t) for t in [[], {}, "", 0, [1], {"a": "n"}, "asdf", 2323]]'  
1000000 loops, best of 3: 1.81 usec per loop 
python -m timeit '[(not not t) for t in [[], {}, "", 0, [1], {"a": "n"}, "asdf", 2323]]' 
1000000 loops, best of 3: 1.11 usec per loop 

我试图用这个来测试它:

>>> [bool(t) == (not not t) for t in [None, [], {}, "", 0, [1], {'a': 'n'}, "asdf", 2323]] 
[True, True, True, True, True, True, True, True, True] 

而且似乎为最常见的情况下工作。可读性

争论不谈,这里这里会失败,或者为什么这是一个糟糕的事是什么?

+4

你很不幸,布尔()是你的应用程序 –

+0

的性能瓶颈@DavidHeffernan笑。这个问题更多的是出于好奇,而不是“优化” – zsquare

+0

有趣的是,我可以在我的机器上确认这些结果。它可能与函数查找有关。 – Kugel

回答

3

正如伊格纳西奥指出,无论bool()not调用相同的方法(见operator.not___nonzero__,和记有大约__len__),所以没有必要对他们在不同的对象类型进行比较。

,如果你只测试操作员/函数调用(这是一个使用IPython中的%timeit魔术方法)你会得到更准确的结果:

 
In [1]: %timeit not not 0 
10000000 loops, best of 3: 60.2 ns per loop 

In [2]: %timeit bool(1) 
1000000 loops, best of 3: 180 ns per loop 

In [3]: %timeit bool(0) 
1000000 loops, best of 3: 177 ns per loop 

In [4]: %timeit not not 1 
10000000 loops, best of 3: 60.5 ns per loop 

和Paulo的建议:

 
In [3]: %timeit True if 0 else False 
10000000 loops, best of 3: 73 ns per loop 

In [4]: %timeit True if 1 else False 
10000000 loops, best of 3: 54.4 ns per loop 

还有一更多,对于funsies:

 
In [6]: %timeit 0 and True or False 
10000000 loops, best of 3: 72.7 ns per loop 

In [7]: %timeit 1 and True or False 
10000000 loops, best of 3: 78.1 ns per loop 

(所有这些测试都针对Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53), [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin

所以,要回答你的问题,“会[使用不是]是一件坏事”。:是的,当然。如果你关心的可读性,bool(…)更清晰,如果你关心性能,True if … else False更快。

+1

有趣的是,似乎有一个“真实”情况下的捷径... –

1

这两个操作都会调用相同的方法(在3.x上的2.x,__bool__()上的__nonzero__()),所以两者都会具有相同的故障模式。