Вопрос-Ответ

Boolean operators vs Bitwise operators

Логические операторы против побитовых операторов

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


  • and против &

  • or против |

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

Переведено автоматически
Ответ 1

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


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

  • Логические операторы являются короткозамыкающими, но побитовые операторы не являются короткозамыкающими.

Поведение короткого замыкания полезно в выражениях, подобных этому:

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

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

Ответ 2

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

0 < 1 & 0 < 2

против

0 < 1 and 0 < 2

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

Ответ 3

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

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


  1. and и or короткое замыкание, например, True or sys.exit(1) не завершится, потому что для определенного значения первого операнда (True or ..., False and ...) второе значение не изменит результат, поэтому его не нужно вычислять. Но | и & не закорачивайте - True | sys.exit(1) выбрасывает вас из REPL.

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

    • Это также относится к некоторым другим языкам с перегрузкой операторов



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

    • Это также относится к некоторым другим языкам, таким как Ruby, Perl и Javascript



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

Ответ 4

Если вы пытаетесь выполнять поэлементные логические операции в numpy, ответ несколько иной. Вы можете использовать & and | для поэлементных логических операций, но and 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)
python