#python #python-3.x #boolean
#python #python-3.x #логическое
Вопрос:
Я наблюдал следующее поведение в python 3:
>>> ([False, True] and [True, True])
[True, True]
>>> ([False, True] or [True, True])
[False, True]
Я ожидал с точностью до наоборот:
[False, True] and [True, True] = [False and True, True and True] = [False, True]
[False, True] or [True, True] = [False or True, True or True] = [True, True]
Какой смысл имеет наблюдаемое поведение и как я могу добиться желаемого поведения?
Комментарии:
1. чего вы ожидали
[False, True] and [True, True] = [False and True, True and True]
?2. @juanpa.arrivillaga именно так это работает в R и Fortran. Они оценивают векторы поэлементно.
3. R и Fortran используют массивы, а не простые старые списки (следовательно, почему numpy заполняет пробел)
Ответ №1:
Каждый список оценивается как единое целое. [False, True]
имеет значение True, и так оно и есть [True, True]
, потому что только пустой список имеет значение False.
and
возвращает последний элемент True, но or
возвращает первый.
Комментарии:
1. и как мне оценить поэлементно?
2. @rvbarreto вам нужно ввести цикл.
zip
может быть полезно.3. Ни один из этих списков не является
True
. Они просто истинны. Неясно, что вы подразумеваете под True.4. @superbrain они оба вычисляются как
True
при использовании в логическом контексте, потому что они не пустые.5. Я предполагаю, что это может быть правильным, хотя, насколько я знаю, это было бы деталью реализации. В документации
if
, например, говорится только об истине, а не оTrue
.
Ответ №2:
Python не предоставляет поэлементных операций со списками. Вы можете использовать понимание списка:
l1 = [False, True]
l2 = [True, True]
[x and y for x,y in zip(l1, l2)]
#[False, True]
Обратите внимание, что np.bitwise_and
рекомендуемый в другом месте примерно на порядок медленнее.
Комментарии:
1. Проблема с этим вопросом заключается в том, что
list(zip(l1, l2)) == list(l1, l2)
поэтому сложно понять, как на самом деле перебирать все2. @PaulH Я не уверен, что ты имеешь в виду.
list(l1, l2)
в первую очередь, это незаконно.3. извините, я имею в виду это
list(zip(l1, l2)) == [l1, l2]
для приведенных данных примера. Поэтому трудно понять, какие сравнения на самом деле выполняет OP.
Ответ №3:
Вы хотите использовать numpy. Стандартная библиотека python вычисляет:
bool([False, True]) and bool([True, True])
Поскольку оба значения истинны, выбирается последнее (попробуйте 1 and 2
)
если вы сделали:
import numpy
numpy.bitwise_and([False, True], [True, True])
Вы получите то, что хотите.
Если вы не хотите использовать numpy, вам нужно написать представление списка или цикл:
result = [(x and y) for x, y in zip([False, True], [True, True])]
Ответ №4:
Из ссылки:
Выражение
x and y
сначала вычисляет x; если x равно false, возвращается его значение; в противном случае вычисляется y и возвращается результирующее значение.
Ваше выражение ([False, True] and [True, True])
— это x and y
выражение, где вашим x является [False, True]
, а вашим y — [True, True]
. Теперь x — это false или это true? Также из этой документации:
следующие значения интерпретируются как false:
False
,None
, числовой ноль всех типов и пустые строки и контейнеры (включая строки, кортежи, списки, словари, наборы и замороженные наборы). Все остальные значения интерпретируются как true.
Итак, x равно true, и, следовательно, and
операция возвращает y . Это именно то, что вы получили.
Аналогично для or
.
Другой способ получить операции с элементами, которые вы хотите:
>>> x, y = [False, True], [True, True]
>>> from operator import and_, or_
>>> [*map(and_, x, y)]
[False, True]
>>> [*map(or_, x, y)]
[True, True]