> More importantly though, allowing your proposed semantics would cause a lot of silent bugs in code like `if arr == value`, which would be silently true of array inputs. We already diverge from python on what == means, so I see no reason to match the normal semantics of bool.

Eric hits the nail right on the head here. (er, ahh, you're both Eric!)
And this gets worse; not only would `a == b` be true, but so would `a != b`! For the vast majority of arrays, `bool(x != x)` would be True!

I can resonate with Eric F's feelings, because to be honest, I've never been a big fan of the fact that comparison operators return arrays in the first place.  That said... it's a difficult design question, and I can respect the decision that was made; there certainly are a large variety of circumstances where broadcasting these operations are useful. On the other hand, it is a decision that comes with implications that cannot be ignored in many other parts of the library, and truthiness of arrays is one of them.

> I'd be tentatively in favor of deprecating bool(array([1]) with a warning asking for `.squeeze()` to be used, since this also hides a (smaller) class of bugs.

I can get behind this as well, though I just keep wondering in the back of my mind whether there's some tricky but legitimate use case that I'm not thinking about, where arrays of size 1 just happen to have a natural tendency to arise.

On Sat, Aug 19, 2017, 10:34 Eric Firing <efiring@hawaii.edu> wrote:
On 2017/08/18 11:45 AM, Michael Lamparski 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/!

I don't agree.  I think the consistency between bool([]) and
bool(array([])) is worth preserving.  Nothing you have shown is
inconsistent with "Falseness is emptiness", which is quite fundamental
in Python.  The inconsistency is in distinguishing between 1 element and
more than one element.  To be consistent, bool(array([0])) and
bool(array([0, 1])) should both be True.  Contrary to the ValueError
message, there need be no ambiguity, any more than there is an ambiguity
in bool([1, 2]).

Eric
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion