On Thu, Jul 25, 2019 at 4:35 AM Petr Viktorin <encukou(a)gmail.com> wrote:
> It's not the equality operator that errors: `==` means element-wise
> comparison in Numpy. The error would come from a conversion of the array
> to bool:
> >>> numpy.array([1, 2, 3]) == numpy.array([1, 3, 4])
> array([ True, False, False])
> >>> if numpy.array([ True, False, False]):
> ... print('Same!')
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ValueError: The truth value of an array with more than one element is
> ambiguous. Use a.any() or a.all()
This is true of course. I was being overly concise, but `arr1 == arr2`
does not itself (currently) raise any exception. It's only `if arr1==arr2`
But what NumPy does is return a "special" object that has some methods to
convert it into a boolean in different ways. We COULD do that with
`d1.values() == d2.values()` in principle. This "DictValuesComparison"
object could have methods like `.equal_as_set()` and `.equal_as_list()`.
However, that's a lot of machinery for very little gain.
In contrast, a NumPy boolean array is useful for lots of purposes, and it
is something we want independently to have around. Mostly it's a great way
of indexing into another list of numeric elements. But it also can be used
in some less common, but not uncommon ways. A hypothetical
DictValuesComparison object would have nearly no use other than avoiding
wrapping d.values() in list(), which we can already do fine. Sure, maybe
that rare case could be made a little faster with this custom machinery,
but it doesn't feel worthwhile to me.
Therefore, I think the exception with guidance in the message should happen
at actual equality (or inequality) comparison time, not when casting to a
Numpy currently returns False when `==` “doesn't make sense”, but
> apparently has plans to change that:
> >>> numpy.array([1, 2, 3]) == numpy.array([1, 2])
> __main__:1: DeprecationWarning: elementwise comparison failed; this will
> raise an error in the future.
> >>> numpy.array([1, 2, 3]) == numpy.array(['a', 'b'])
> __main__:1: FutureWarning: elementwise comparison failed; returning
> scalar instead, but in the future will perform elementwise comparison
This is very interesting! I did not know about this planned change. That
NumPy will start raising exceptions on equality comparison adds a little
bit of support for my suggestion, I think.
> > So, a helpful error message including something like "Cannot compare
> > dict.values directly, consider converting to sets / lists / sorted
> > lists before comparing" ?
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons. Intellectual property is
to the 21st century what the slave trade was to the 16th.