Sven Marnach と FJ によるソリューションは美しいと思いますが、私の小さなテストでは速くはありません。これは、事前に計算された を使用した Raymond の最適化バージョンset
です。
$ python -m timeit -s "choices = set('abc')" \
-s "x = 'c'" \
-s "y = 'a'" \
"z, = choices - set(x + y)"
1000000 loops, best of 3: 0.689 usec per loop
これは元のソリューションです。
$ python -m timeit -s "x = 'c'" \
-s "y = 'a'" \
"if x == 'a' and y == 'b' or x == 'b' and y == 'a':" \
" z = 'c'" \
"elif x == 'b' and y == 'c' or x == 'c' and y == 'b':" \
" z = 'a'" \
"elif x == 'a' and y == 'c' or x == 'c' and y == 'a':" \
" z = 'b'"
10000000 loops, best of 3: 0.310 usec per loop
6 つの比較すべてを試行する必要があるため、これはステートメントの最悪の入力であることに注意してください。if
と のすべての値でテストするとx
、次の結果y
が得られます。
x = 'a', y = 'b': 0.084 usec per loop
x = 'a', y = 'c': 0.254 usec per loop
x = 'b', y = 'a': 0.133 usec per loop
x = 'b', y = 'c': 0.186 usec per loop
x = 'c', y = 'a': 0.310 usec per loop
x = 'c', y = 'b': 0.204 usec per loop
ベースのset
バリアントは、さまざまな入力に対して同じパフォーマンスを示しますが、一貫して2 ~ 8 倍遅くなります。その理由は、if
ベースのバリアントがはるかに単純なコードを実行するためです。つまり、ハッシュと比較して等価テストです。
どちらのタイプのソリューションも価値があると思います。セットのような「複雑な」データ構造を作成すると、パフォーマンスが低下する一方で、読みやすさと開発速度が大幅に低下することを知っておくことが重要です。コードを変更すると、複雑なデータ型も大幅に改善されます。セットベースのソリューションを 4 つ、5 つ、... の変数に拡張するのは簡単ですが、if ステートメントはすぐにメンテナンスの悪夢に変わります。