#python #bit-manipulation
#python #манипулирование битами
Вопрос:
Какой был бы самый минимальный способ определить, находится ли True
в Python
только один элемент в логическом списке?
Я думал о преобразовании каждого логического значения в 0 (false) или 1 (true) и сложении их всех и проверке, равна ли сумма 1. Это довольно минималистично, но мне было интересно, существует ли (побитовая) операция, которая вернет true, если только один элемент имеет значение true, а все остальные false, что избавило бы меня от преобразования bool—> int (каким бы простым оно ни было). В основном мне просто любопытно, существует ли такая побитовая операция.
Ответ №1:
bool
Подкласс Python из int
, поэтому вам не нужно выполнять какое-либо преобразование:
>>> sum([True, False, False])
1
>>> sum([True, True, True])
3
Однако это решение не приводит к короткому замыканию… есть некоторые случаи, когда вы, возможно, захотите иметь возможность выйти из системы раньше:
result = 0
for item in boolean_iterable:
result = item
if result > 1:
break # Short-circuit early
Однако, если ваши логические итерации действительно велики и вы не ожидаете частого короткого замыкания, я бы ожидал, что это будет работать хуже, чем sum
в среднем случае (что может подтолкнуть цикл к более оптимизированному коду).
Также, если вы ищете умные способы сделать это с помощью побитовой арифметики, вы можете использовать xor
в reduce
операции:
>>> from functools import reduce
>>> import operator
>>> reduce(operator.xor, [True, False, False], False)
True
>>> reduce(operator.xor, [True, False, True], False)
False
>>> reduce(operator.xor, [], False)
False
>>> reduce(operator.xor, [True], False)
True
Но я бы не советовал использовать эту версию
Комментарии:
1. Я полагаю, что во втором коде есть ошибка, вы, вероятно, имели в виду
result
переменную в условии.2. @table — Спасибо :-). Это это то, что я имел в виду. Вот почему у нас есть модульные тесты:-p
3. К сожалению, это создает
TypeError
исключение, если в миксе есть какие-либоNone
значения.4. @MicahWalter — вероятно, с этим не так уж сложно справиться — просто деформируйте логическую итерацию в выражении генератора, которое удаляет или преобразует
None
значения по вашему усмотрению.