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 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 1
10000000 ループ、ベストオブ 3: ループあたり 60.5 ns

そしてパウロの提案:

[3]: %timeit 0 の場合は True、そうでない場合は False
10000000 ループ、ベストオブ 3: ループあたり 73 ns

[4]: %timeit 1 の場合は True、そうでない場合は False
10000000 ループ、ベスト オブ 3: ループあたり 54.4 ns

そしてもう1つ、ファンシーのために:

[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)

したがって、あなたの質問に答えるには、「[using not] を行うのは悪いことです」: はい、間違いなく。読みやすさを重視する場合bool(…)はより明確になり、パフォーマンスを重視する場合True if … else Falseは高速になります。

于 2012-11-07T07:40:32.107 に答える
1

__nonzero__()どちらの操作も同じメソッド ( 2.x では、 3.x では)を呼び出すため、__bool__()どちらも同じ障害モードになります。

于 2012-11-07T07:26:02.223 に答える