2012-11-07 103 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__()),所以兩者都會具有相同的故障模式。