Tom*_*mas 1 python arrays heap numpy
有人可以解释为什么以下代码会导致 ValueError 吗?
import heapq
import numpy as np
a = np.ones((2, 2), dtype=int)
states = []
heapq.heappush(states, (0, a))
heapq.heappush(states, (0, a.copy()))
Run Code Online (Sandbox Code Playgroud)
错误信息是:
Traceback (most recent call last):
File "x.py", line 8, in <module>
heapq.heappush(states, (0, a.copy()))
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
运行它而不将它添加a.copy()到堆中可以正常工作,第二个/后续的由于某种原因是一个问题。我确实理解数组有一个未知的真值方面,[True, False, True]并且不可能确定单个True或False从中确定,但为什么heapq需要这样做?尤其是仅在第二种情况下?
TL;DR:因为如果 numpy 数组包含多个元素,则它们不能转换为布尔值。
关于堆的一些信息:
堆“排序”它们的内容(因此项目必须实现,<但这是一个实现细节)。
但是,您可以heap通过tuple为项目创建s 来将项目插入到 中,其中第一个元素是某个值,第二个元素是数组。
比较元组首先检查第一项是否相等,如果相等,则检查第二项是否相等,依此类推,直到它们不相等,然后它会检查它是更小(当操作为 时<)还是更大(为>)。然而元组是在 C 中实现的,并且==检查与 Python 中的检查有点不同。它使用PyObject_RichCompareBool. 尤其是“注释”在这里很重要
如果
o1和o2是同一个对象,PyObject_RichCompareBool()将始终返回 1 forPy_EQ和 0 forPy_NE。
现在让我们转到 numpy 数组:
如果numpy.arrayabool包含多个项目,则无法将 a 转换为 a :
>>> 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()
Run Code Online (Sandbox Code Playgroud)
一个if检查隐式转换的条件为布尔值:
>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
即使在比较 numpy-arrays 之后,它们仍然是 numpy 数组:
>>> arr > arr
array([False, False], dtype=bool)
>>> arr == arr
array([ True, True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)
所以这些不能用以下方法评估==:
>>> if arr == arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
因此,您不能将具有多个元素的 numpy 数组转换为布尔值!然而现在有趣的部分来了:heapq-module 使用PyObject_RichCompareBool()它可以检查两个数组是否相等,但当且仅当它们相同!
这就是为什么它可以与多次传入的相同数组一起使用,但在复制它时却失败了:
>>> arr is arr
True
>>> arr is arr.copy()
False
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2381 次 |
| 最近记录: |