我使用Python的unittest模块,并且要检查两个复杂数据结构是否相等。对象可以是具有各种值的数字列表:数字,字符串,Python容器(列表/元组/ dicts)和numpy数组。后者是提出这个问题的原因,因为我不能做
self.assertEqual(big_struct1, big_struct2)
因为它产生一个
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
我想我需要为自己写平等考试。它应该适用于任意结构。我目前的想法是一个递归函数:
尝试将arg1的当前“节点”直接对应到arg2的对应节点;
>如果没有异常提出,移动(也在这里处理“终端”节点/叶子);
>如果ValueError被捕获,更深入,直到找到一个numpy.array;
>比较阵列(例如like this)。
跟踪两个结构的“对应”节点似乎有点问题,但也可能是zip。
问题是:这种做法有什么好(更简单)的替代方法吗?也许numpy为此提供了一些工具?如果没有建议的替代方案,我会实施这个想法(除非我有一个更好的),并作为答案发布。
附:我有一个模糊的感觉,我可能已经看到一个解决这个问题的问题,但我现在找不到。
P.P.S.一种替代方法是遍历结构并将所有numpy.arrays转换为列表的功能,但这更容易实现吗?对我来说也是一样
编辑:Subclassing numpy.ndarray听起来非常有希望,但显然我没有将比较的两面硬编码成一个测试。其中一个确实是硬编码的,所以我可以:
>使用numpy.array的自定义子类填充它;
> jterrace‘s answer中的change isinstance(other,SaneEqualityArray)to isinstance(other,np.ndarray);
>在比较中总是使用它作为LHS。
我在这方面的问题是:
>它会工作(我的意思是,这听起来对我有用,但也许一些棘手的边缘案例将无法正确处理)按照我的期望,递归平等检查中我的自定义对象是否总是最终成为LHS?
>再次,有更好的方法(给定我至少有一个结构与真正的numpy数组)。
编辑2:我试过了,(看似)的工作实现显示在this answer。