【发布时间】:2021-04-26 18:13:20
【问题描述】:
我使用namedtuple定义了一个自定义数据结构,其中包含numpy数组。
from collections import namedtuple
import numpy as np
AA = namedtuple('AA', 'name, x')
c = []
c.append(AA('x', np.arange(3)))
c.append(AA('x', np.arange(3)))
c.append(AA('y', np.arange(3)))
c[0] in c
c[1] in c
c[2] in c
奇怪的是,c[1] 测试失败了,而其他两个测试成功了。
ValueError Traceback (most recent call last)
<ipython-input-70-c1daf83cd082> in <module>
----> 1 c[1] in c
ValueError: The truth value of an array with more than one element is ambiguous. Use c.any() or c.all()
该错误似乎与 numpy 数组相等性测试 c[0].x == c[1].x 有关。但是由于某种原因,第一个元素的成员资格测试总是成功
s = []
s.append(np.arange(3))
s.append(np.arange(3))
s[0] in s
s[1] in s
另见此示例
class A:
def __eq__(self, other):
raise ValueError
a = [A(), A()]
a[0] in a
a[1] in a
我也不知道为什么c[2] in c返回True。
【问题讨论】:
-
c[0] in c这会问“c 的第一个元素是 c 的成员吗?”,这显然是正确的。这里的目的是什么? -
@JohnGordon 和
c[1] in c对第二个元素提出了同样的问题,但它失败了。这就是问题所在。奇怪的是,如果你添加了第三个元素的副本,那么项目 1 和 3 会失败,但不会失败 0 和 2。我需要考虑这个。 -
Numpy
eq可能会在比较元素之前检查id、data、shape。因此c[1] in c失败,s[1] in s和np.arange(3) in s也是如此,因为在这种情况下,比较会降级为逐元素比较。 -
好的,只有在必须检查数组的情况下才会失败。如果“名称”元素不同,则不必检查数组。
-
不管怎样,同样的事情发生在一个普通的(未命名的)元组上。