[Numpy-discussion] Why are empty arrays False?

Paul Hobson pmhobson at gmail.com
Fri Aug 18 18:37:52 EDT 2017

```Maybe I'm missing something.

This seems fine to me:
>>> bool(np.array([]))
False

But I would have expected these to raise ValueErrors recommending any() and
all():
>>> bool(np.array([1]))
True
>>> bool(np.array([0]))
False

On Fri, Aug 18, 2017 at 3:00 PM, Stephan Hoyer <shoyer at gmail.com> wrote:

> I agree, this behavior seems actively harmful. Let's fix it.
>
> On Fri, Aug 18, 2017 at 2:45 PM, Michael Lamparski <
> diagonaldevice at gmail.com> wrote:
>
>> Greetings, all.  I am troubled.
>>
>> The TL;DR is that `bool(array([])) is False` is misleading, dangerous,
>> and unnecessary. Let's begin with some examples:
>>
>> >>> bool(np.array(1))
>> True
>> >>> bool(np.array(0))
>> False
>> >>> bool(np.array([0, 1]))
>> ValueError: The truth value of an array with more than one element is
>> ambiguous. Use a.any() or a.all()
>> >>> bool(np.array([1]))
>> True
>> >>> bool(np.array([0]))
>> False
>> >>> bool(np.array([]))
>> False
>>
>> One of these things is not like the other.
>>
>> The first three results embody a design that is consistent with some of
>> the most fundamental design choices in numpy, such as the choice to have
>> comparison operators like `==` work elementwise.  And it is the only such
>> design I can think of that is consistent in all edge cases. (see footnote 1)
>>
>> The next two examples (involving arrays of shape (1,)) are a
>> straightforward extension of the design to arrays that are isomorphic to
>> scalars.  I can't say I recall ever finding a use for this feature... but
>> it seems fairly harmless.
>>
>> So how about that last example, with array([])?  Well... it's /kind of/
>> like how other python containers work, right? Falseness is emptiness (see
>> footnote 2)...  Except that this is actually *a complete lie*, due to /all
>> of the other examples above/!
>>
>> Here's what I would like to see:
>>
>> >>> bool(np.array([]))
>> ValueError: The truth value of a non-scalar array is ambiguous. Use
>> a.any() or a.all()
>>
>> Why do I care?  Well, I myself wasted an hour barking up the wrong tree
>> while debugging some code when it turned out that I was mistakenly using
>> truthiness to identify empty arrays. It just so happened that the arrays
>> always contained 1 or 0 elements, so it /appeared/ to work except in the
>> rare case of array([0]) where things suddenly exploded.
>>
>> I posit that there is no usage of the fact that `bool(array([])) is
>> False` in any real-world code which is not accompanied by a horrible bug
>> writhing in hiding just beneath the surface. For this reason, I wish to see
>> this behavior *abolished*.
>>
>> Thank you.
>> -Michael
>>
>> Footnotes:
>> 1: Every now and then, I wish that `ndarray.__{bool,nonzero}__` would
>> just implicitly do `all()`, which would make `if a == b:` work like it does
>> for virtually every other reasonably-designed type in existence.  But then
>> I recall that, if this were done, then the behavior of `if a != b:` would
>> stand out like a sore thumb instead.  Truly, punting on 'any/all' was the
>> right choice.
>>
>> 2: np.array([[[[]]]]) is also False, which makes this an interesting sort
>> of n-dimensional emptiness test; but if that's really what you're looking
>> for, you can achieve this much more safely with `np.all(x.shape)` or
>> `bool(x.flat)`
>>
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at python.org
>> https://mail.python.org/mailman/listinfo/numpy-discussion
>>
>>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
> https://mail.python.org/mailman/listinfo/numpy-discussion
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20170818/0e9d1c8a/attachment.html>
```