4

要将值类型转换为布尔值,我通常执行以下操作:

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

2 回答 2

4

正如 Ignacio 所指出的,两者都bool()调用not相同的方法(参见operator.not___nonzero__以及关于 的注释__len__),因此无需在不同的对象类型之间进行比较。

如果您只测试操作符/函数调用(这是使用 ipython 的%timeit魔术方法),您将获得更准确的结果:

在 [1] 中:%timeit not not not 0
10000000 次循环,3 次中的最佳:每个循环 60.2 ns

在 [2] 中:%timeit bool(1)
1000000 次循环,3 次中的最佳:每个循环 180 ns

在 [3] 中:%timeit bool(0)
1000000 次循环,3 次中的最佳:每个循环 177 ns

在 [4] 中:%timeit not not not 1
10000000 次循环,3 次中的最佳:每个循环 60.5 ns

和保罗的建议:

在 [3] 中:%timeit True if 0 else False
10000000 次循环,3 次中的最佳:每个循环 73 ns

在 [4] 中: %timeit True if 1 else False
10000000 次循环,3 次中的最佳:每个循环 54.4 ns

还有一个,对于有趣的:

在 [6] 中:%timeit 0 和 True 或 False
10000000 次循环,最佳 3:每循环 72.7 ns

在 [7] 中:%timeit 1 和 True 或 False
10000000 次循环,3 次中的最佳:每个循环 78.1 ns

(所有这些测试都针对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则更快。

于 2012-11-07T07:40:32.107 回答
1

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

于 2012-11-07T07:26:02.223 回答