Истинен ли только один элемент в логическом списке?

#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 значения по вашему усмотрению.