Не понимаю, почему (5 | -2)> 0 - Ложь, где (5 или -2)> 0 - Истина
Это довольно тривиальный вопрос, на который я так и не смог найти ответ.
Здесь проблема. У меня есть следующий массив:
vals = [-5, 2]
И я хочу проверить, больше ли val[0]
или val[1]
чем 0. Если либо true, то я должен вывести True.
Моей непосредственной мыслью было использовать; (vals[1] or vals[0]) > 0)
но я нахожу, что (5 | -2) > 0
- False, где (5 or -2) > 0
- True
Любое разъяснение будет высоко ценится.
Ответы
Ответ 1
В чем разница между or
и |
?
or
является логическим или и |
является побитовым или логическим включением или.
Логический или
Логическое или в Python возвращает первое значение, которое является истинным.
Пример:
>>> None or False or 5
5
>>> -5 or 2
-5
Побитовое или логическое включение или
Побитовый или логический включительно или представлен символом |
Оператор в Python и создает число, где установлены все биты, которые установлены по крайней мере в одном из заданных номеров.
Пример:
- 2 находится в двоичном формате
0010
- 4 в двоичном коде
0100
Логическое или между двумя результатами в 0110
который равен 6.
>>> 2 | 4
6
Как хранится отрицательное число, обычно зависит от реализации. Однако в большинстве систем отрицательное число сохраняется, создавая два дополнения положительного числа, инвертируя каждый бит и добавляя 1.
Это число в побитовых или двух других числах по-прежнему приводит к отрицательному числу:
>>> -5 | 2
-5
Ни один из двух не решает вашу проблему
При использовании
(vals[1] or vals[0]) > 0
Кажется, работает, он не работает, когда вы переворачиваете значения:
>>> vals = [2, -5]
>>> (vals[1] or vals[0]) > 0
False
Вы должны проверить оба значения отдельно
>>> vals = [-5, 2]
>>> vals[0] > 0 or vals[1] > 0
True
Для большего ввода это может быть неудобно. Вы должны использовать любой с выражением генератора:
>>> any(x > 0 for x in vals)
True
Ответ 2
Вы хотите any
функцию:
>>> any(x > 0 for x in vals)
x | y
x | y
вычисляет побитовое OR
двух значений, в то время как x or y
вычисляет первое "истинное" значение. В обоих случаях результат сравнивается с 0
: (x or y) > 0
и (x | y) > 0
.
Что вы хотите сравнить каждое значение до нуля (при необходимости), с
vals[0] > 0 or vals[1] > 0
Если бы у вас было три значения, вы бы написали
vals[0] > 0 or vals[1] > 0 or vals[2] > 0
any
функция обобщает это для списка любого размера, без необходимости решать, сколько терминов or
вместе на основе размера списка.
Ответ 3
Чтобы ответить на этот вопрос, я должен объяснить о двух дополнениях.
Двоичное представление чисел
Итак, вы знаете, как внутри целое число, подобное 5, представляется в виде двоичной строки
00000000000000000000000000000101
Как вы себе представляете отрицательное число?
Ну, вот что мы хотим сделать:
-
Сложение должно работать одинаково с отрицательными числами и положительными числами; то есть вы делаете те же шаги, чтобы добавить 4 + 9 к 4 + -9.
-
Целочисленное переполнение не должно нарушать математику; т.е. MAX_VALUE + 1 == MIN_VALUE
, MIN_VALUE - 1 == MAX_VALUE
То, что мы делаем, называется "Два дополнения".
ДВА КОМПЛЕМЕНТА
Чтобы представить отрицательное число, возьмите его абсолютное значение, сдвиньте каждый бит и добавьте 1.
Так что, если положительное число 5
00000000000000000000000000000101
отрицательное число -5
11111111111111111111111111111011
По сути, это означает, что мы выбираем число 01111111111111111111111111111111
как наибольшее положительное число, и все числа после этого являются отрицательными.
ТАК ЧТО ОЗНАЧАЕТ (5 | -2)?
|
является побитовым или оператором. Учитывая два числа, он берет каждый бит и/или их вместе, создавая новое число, где цифра равна 1, если цифра в этой позиции в холке или обоих из двух исходных чисел равна 1, и 0 в противном случае. Расчет выглядит так:
5 -> 00000000000000000000000000000101
| -2 -> 11111111111111111111111111111110
---- --------------------------------
11111111111111111111111111111111 -> -1
Итак, как вы можете видеть, 5 | -2 = -1 <0.
О чем (5 или -2)?
Оператор "или" принимает два значения, приводит их к логическим значениям и/или к ним вместе. Это важно: это не так или значения, он возвращает первое значение, которое является "правдивым" - иными словами, если вы поместите его в оператор if, он запустится.
Единственное целое число, которое не является "правдивым", равно 0. Поэтому (5 или -2) возвращает первое ненулевое целое число 5 и 2, которое равно 5> 0. Таким образом, 5 или -2 = 5> 0.
Ответ 4
|
является побитовым ИЛИ, и Python использует два представления дополнения для целых чисел. Оценка 5 | -2
5 | -2
дает:
... 0000 0000 0000 0101 (+5)
| ... 1111 1111 1111 1110 (-2)
──────────────────────────────
= ... 1111 1111 1111 1111 (-1)
И -1 не больше нуля, поэтому (5 | -2) > 0
ложно.
or
является логическим ИЛИ. В отличие от других языков, где этот оператор возвращает логическое (True/False) значение, Python определяет x or y
как эквивалентное x if x else y
(за исключением того, что x вычисляется только один раз). Обратите внимание, что любое ненулевое числовое значение является "правдивым" в Python, поэтому, если x ≠ 0, то x or y
оценивается как x
.
>>> 5 or -2
5
>>> -2 or 5
-2
То, что (5 or -2) > 0
оценивается как "Истина", было удачей, если сначала было положительное число. В другом порядке вы бы получили Ложь.
В целом (x or y) > 0
не эквивалентно (x > 0) or (y > 0)
, что вы и имели в виду.
Ответ 5
Когда вы делаете (5 | -2)
, вы делаете побитовое ИЛИ. Это сохранит бит отрицания в числах. Поэтому у вас все равно будет отрицательное число.
(5 or -2)
- это логическое ИЛИ, интерпретатор Python распространит его на следующий логический оператор (больше, чем).
Ответ 6
Это две совершенно разные операции, так что это ожидаемо.
Для иллюстрации приведем небольшой журнал оболочки:
In [1]: 5 or -2
Out[1]: 5
In [2]: 5 | -2
Out[2]: -1
Оператор or
возвращает первое non- нулевое (non- None
, non- False
и т.д.) Значение.
|
оператор делает побитовый или. Проиллюстрировать:
In [3]: bin(5)
Out[3]: '0b101'
In [4]: bin(-2)
Out[4]: '-0b10'
In [5]: bin(5 | -2)
Out[5]: '-0b1'