#python #numpy #comparison #operators #boolean-expression
#python #numpy #сравнение #операторы #логическое выражение
Вопрос:
В Python вы можете сделать следующее;
>>> 3 < 4 < 5
True
>>> 3 < 4 < 4
False
Как это работает? Я бы подумал, что 4 < 5
это вернет логическое значение, и поэтому 3 < True
должно вернуться False
, или 3 < 4
должно вернуть логическое True < 4
значение, и поэтому, возможно, должно вернуться True
, если True
может быть приведено как целое число 1 ?.
И почему это не работает для массивов numpy?
>>> 1 < np.array([1, 2, 3]) < 3
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Можно ли заставить его работать для массивов numpy?
Комментарии:
1. Оно оценивается как
3 < 4 and 4 < 5
. Кроме того, ошибка numpy, которую вы получаете, не имеет ничего общего с тем фактом, что вы объединяете операторы вместе. Скорее, это связано с тем фактом, что достоверность массива numpy с более чем одним значением неоднозначна, как говорится в сообщении об ошибке. Вы бы получили ту же ошибку, если бы просто сделалиbool(np.array([1, 2, 3]))
.2. @PaulM. Тогда почему это не работает для массивов numpy? « 1 < np.array([1, 2, 3]) и np.array([1, 2, 3]) < 3 Трассировка (последний последний вызов): файл «<input>», строка 1, в <module> ValueError: истинное значениемассив с более чем одним элементом неоднозначен. Используйте.any() или.all() « Тогда почему я не могу сделать; « np.array([1]) < np.array([1, 2, 3]) < np.array([3]) Обратная трассировка (самая последняявызовите последний): Файл «<input>», строка 1, в <module> Ошибка значения: значение истинности массива с более чем одним элементом неоднозначно. Используйте.any() или.all() «
3. К вашему сведению, эта функция существует как минимум с версии 2.7 , которая сейчас является EOL, поэтому я удалил эту часть вопроса, поскольку это не очень важно.
4. @wjandrea хорошо, мой плохой, спасибо за редактирование.
5. @PaulM. — ваша перезапись неверна, поскольку вы применяете
all()
к исходному массиву numpy, а не к результату сравнения его с целым числом. Упрощение вашей перезаписи0 < True < 5
, что, очевидно, бесполезно.
Ответ №1:
Согласно документам Python:
Сравнения могут быть скомпонованы произвольно, например,
x < y <= z
эквивалентноx < y and y <= z
, за исключением того, что вычисляетсяy
только один раз (но в обоих случаяхz
вообще не вычисляется, когдаx < y
оказывается ложным).
Итак, ваш пример эквивалентен:
1 < np.array([1, 2, 3]) and np.array([1, 2, 3]) < 3
таким образом, ожидается, что каждый подтерм приведет к логическому значению. Но подтерминал:
1 < np.array([1, 2, 3])
в результате создается новый массив numpy, содержащий:
[False, True, True]
Именно это значение Python пытается интерпретировать как логическое значение. Это не удается сделать, выдавая сообщение об ошибке:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Я ожидаю, что желаемое выражение здесь:
(1 < np.array([1, 2, 3])).all() and (np.array([1, 2, 3]) < 3).all()
который нельзя упростить, чтобы использовать цепочку сравнения.
Комментарии:
1. Именно
evaluated only once
это делает двустороннее выражение особенным. В противном случае это просто синтаксический ярлык. Поэтому необходимость использовать два отдельных сравнения вnumpy
не является большой потерей. Посколькуnumpy
сравнения выполняются по элементам, у вас есть выбор при создании логических комбинаций.2. @hpaulj — Я не согласен ни с чем, что вы говорите. Более эквивалентное выражение с точки зрения эффективности или даже функции может включать извлечение создания массива numpy в отдельную функцию, чтобы это происходило только один раз. Я просто отвечал на вопрос «почему», который не требовал вникания в эту тонкость. Учитывая существование
[1, 2, 3]
в рассматриваемом выражении, это явно не производственный код.3. Я должен был указать, что мой комментарий был направлен больше на OP, чем на вас. Я предполагаю, что OP уведомлен о комментариях в ответах, поэтому не пытался добавить
@
.4. @hpaulj — ah. имеет смысл. извините, я воспринял это как направленное на меня.