Я думаю, что решение Свена Марнаха и FJ прекрасно, но в моем маленьком тесте оно не быстрее.Это оптимизированная версия Раймонда с использованием предварительно вычисленного 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
Обратите внимание, что это худший возможный ввод для 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
выполняет гораздо более простой код: тесты на равенство по сравнению с хешированием.
Я думаю, что оба типа решений являются ценными: важно знать, что создание "сложных" структур данных, таких как наборычто-то стоит вам в производительности - в то время как они дают вам большую читабельность и скорость разработки .Сложные типы данных также значительно улучшаются при изменении кода: решение, основанное на множестве, легко расширить до четырех, пяти, ... переменных, тогда как операторы if быстро превращаются в кошмар обслуживания.