Булевы операторы против побитовых операторов - PullRequest
61 голосов
/ 02 октября 2010

Я не совсем понимаю, когда мне следует использовать логические и битовые операторы

and vs &, or vs |

Может ли кто-нибудь объяснить мне, когда я использую каждый из них и когда использование одного над другим повлияет на мои результаты?

Ответы [ 8 ]

58 голосов
/ 02 октября 2010

Вот несколько рекомендаций:

  • Булевы операторы обычно используются для логических значений, но побитовые операторы обычно используются для целых значений.
  • Булевы операторы короткозамкнуты , но побитовые операторы не коротко замкнуты.

Режим короткого замыкания полезен в выраженияхкак это:

if x is not None and x.foo == 42:
    # ...

Это не будет работать правильно с побитовым оператором &, потому что обе стороны всегда будут оцениваться, давая AttributeError: 'NoneType' object has no attribute 'foo'.Когда вы используете логический оператор and, второе выражение не оценивается, если первое - False.Точно так же or не оценивает второй аргумент, если первый равен True.

19 голосов
/ 02 октября 2010

Теоретически and и or происходят из логической логики (и, следовательно, работают с двумя логическими значениями для получения логического значения), тогда как & и | применяют логическое значение и / или к отдельным битам целые числа. Здесь много вопросов о том, как последние работают точно.

Вот практические различия, которые потенциально могут повлиять на ваши результаты:

  1. and и or короткое замыкание, то есть True or sys.exit(1) не выйдет, потому что для определенного значения (True or ..., False and ...) первого операнда второй не изменит результат = не нужно оценивать. Но | и & не закорачивают - True | sys.exit(1) выбрасывает вас из REPL.
  2. (применяется только к некоторым языкам с перегрузкой операторов, включая Python :) & и | являются обычными операторами и могут быть перегружены - and и or подделаны в язык (хотя бы в Python, специальный метод приведения к логическому значению может иметь побочные эффекты).
  3. (относится только к нескольким языкам [см. Комментарий KennyTM] :) and и or возвращают (всегда? Никогда не понимали этого, и при этом мне это не нужно) значение операнда вместо True или False. Это не меняет значения логических выражений в условиях - 1 or True равно 1, но 1 также верно. Но когда-то он использовался для эмуляции условного оператора (cond ? true_val : false_val в синтаксисе C, true_val if cond else false_val в Python уже несколько лет). Для & и | тип результата зависит от того, как операнды перегружают соответствующие специальные методы (True & False равно False, 99 & 7 равно 3, для наборов это объединения / пересечение ...).

Но даже когда, например, a_boolean & another_boolean будет работать идентично, правильное решение использует and - просто потому, что and и or связаны с логическим выражением и условием, в то время как & и | означают сдвиг битов.

16 голосов
/ 20 сентября 2014

Вот еще одно отличие, которое на некоторое время меня озадачило: потому что & (и другие побитовые операторы) имеют более высокий приоритет, чем and (и другие булевы операторы), следующие выражения оценивают различные значения:

0 < 1 & 0 < 2

против

0 < 1 and 0 < 2

То есть, первое дает False, поскольку оно эквивалентно 0 < (1 & 0) < 2, следовательно, 0 < 0 < 2, следовательно, 0 < 0 and 0 < 2.

4 голосов
/ 03 августа 2016

Если вы пытаетесь выполнять поэлементные логические операции в numpy, ответ будет несколько другим.Вы можете использовать & и | для поэлементных логических операций, но and и or вернут ошибку значения.

Чтобы быть в безопасности, вы можете использовать numpy логические функции .

np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False,  True], dtype=bool)

np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False,  True], dtype=bool)
2 голосов
/ 02 октября 2010

Подсказка в названии:

  • Логические операторы предназначены для выполнения логических операций (проверка истинности, распространенная в программировании и формальной логике)
  • Битовые операторыпредназначены для "бит-тиддлинг" (низкоуровневая обработка битов в байтовых и числовых типах данных)

Хотя это возможно и действительно иногда желательно (обычно из соображений эффективности)Выполняйте логические операции с побитовыми операторами, вы, как правило, должны избегать их для таких целей, чтобы предотвратить незаметные ошибки и нежелательные побочные эффекты.

Если вам нужно манипулировать битами, то побитовые операторы создаются специально.Веселая книга: Хакерский восторг содержит несколько классных и действительно полезных примеров того, чего можно достичь с помощью бит-твидлинга.

2 голосов
/ 02 октября 2010

Логические операции являются логическими операциями.

Битовые операции - это операции над двоичными битами.

Битовые операции:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

Операции:

And & 1 if both bits are 1, 0 otherwise
Or  | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit

Некоторые применения побитовых операций:

1) Установка и очистка битов

Логические операции:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 
1 голос
/ 21 мая 2018

Общее правило - использовать соответствующий оператор для существующих операндов.Используйте логические (логические) операторы с логическими операндами и побитовые операторы с (более широкими) интегральными операндами (примечание: False эквивалентно 0 и True to 1 ).Единственный «хитрый» сценарий - применение булевых операторов к не булевым операндам.
Давайте рассмотрим простой пример, как описано в [SO]: Python - различия между 'и' и '&' [duplicate] : 5 & 7 и 5 and 7.

Для побитовых и ( & ) все довольно просто:

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

Для логических и вот что [Python 3]: логические операции состояния ( выделение - мое):

(Обратите внимание, что ни и , ни , ни не ограничивают возвращаемое значение и тип False и True , а точнее возвращает последний оцененный аргумент .

Пример :

>>> 5 and 7
7
>>> 7 and 5
5

Конечно,то же самое относится к | против или .

0 голосов
/ 27 сентября 2017

Boolean 'и' vs. Bitwise '&':

Псевдокод / ​​Python помог мне понять разницу между ними:

def boolAnd(A, B):
    # boolean 'and' returns either A or B
    if A == False:
        return A
    else:
        return B

def bitwiseAnd(A , B):
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.)

    binA = binary(A)
    binB = binary(B)



    # perform boolean 'and' on each pair of binaries in (A, B)
    # then return the result:
    # equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])

    # assuming binA and binB are the same length
    result = []
    for i in range(len(binA)):
      compar = boolAnd(binA[i], binB[i]) 
      result.append(compar)

    # we want to return a string of 1s and 0s, not a list

    return ''.join(result)
...