TL; DR: Поскольку массивы numpy не могут быть переведены в логическое, если они содержат более одного элемента.
Некоторые сведения о кучах:
Кучи «порядок» их содержимое (поэтому детали должны реализовать <
но это деталь реализации).
Вы, однако, вставляете элементы в heap
, создавая tuple
s для элементов, где первые элементы являются некоторым значением, а второе - массивом.
Сравнение кортежей сначала проверяет, совпадают ли первые элементы, и если они проверяют, совпадают ли эти два элемента и так далее, пока они не станут равными, тогда он будет проверять, меньше ли это (когда операция была <
) или больше (для >
). Однако кортежи реализованы в C, а проверка ==
немного отличается от таковой в Python. Он использует PyObject_RichCompareBool
. Особенно «примечание» важно здесь
Если o1
и o2
являются тот же объект, PyObject_RichCompareBool()
всегда возвращает 1 для Py_EQ
и 0 для Py_NE
.
Теперь давайте перейдем к Numpy массивов:
Вы не можете преобразовать numpy.array
к bool
, если она содержит более одного элемента:
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
if
проверка неявно преобразует условие a boolean:
>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Даже после сравнения numpy-arra YS они все еще Numpy массивы:
>>> arr > arr
array([False, False], dtype=bool)
>>> arr == arr
array([ True, True], dtype=bool)
Таким образом, они не могут быть оценены с ==
:
>>> if arr == arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Таким образом, вы не можете преобразовать Numpy-массивы с более чем одного элемента в булево! Однако теперь идет интересная часть: heapq
-модуль использует PyObject_RichCompareBool()
, поэтому он может проверить, равны ли два массива, но , если и только если одинаковы!
Вот почему он работает с такой же массив передается в несколько раз, но он терпит неудачу, когда вы копируете его:
>>> arr is arr
True
>>> arr is arr.copy()
False
heapq необходимо сравнить элементы кучи. Кучевые элементы являются кортежами, а первые записи кортежей равны, поэтому он сравнивает второй элемент. Сравнение вторых элементов не приводит к чему-то, что можно интерпретировать как логическое. – user2357112
Обратите внимание, что 'heapq.heappush (heap, (x, y))' не означает "push вещь' y' с приоритетом 'x'; это означает «push thing» (x, y) '. У нас нет отдельных приоритетов и элементов; у нас просто есть элементы. – user2357112