[Numpy-discussion] preferred way of testing empty arrays

Robert Kern robert.kern at gmail.com
Fri Jan 27 15:59:03 EST 2012


On Fri, Jan 27, 2012 at 20:46, Bartosz Telenczuk
<b.telenczuk at biologie.hu-berlin.de> wrote:
> I have been using numpy for several years and I am very impressed with its flexibility. However, there is one problem that has always bothered me.
>
> Quite often I need to test consistently whether a variable is any of the following: an empty list, an empty array or None. Since both arrays and lists are ordered sequences I usually allow for both, and convert if necessary. However, when the (optional) argument is an empty list/array or None,  I skip its processing and do nothing.
>
> Now, how should I test for 'emptiness'?
>
> PEP8 recommends:
>
> For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
>
>>> seq = []
>>> if not seq:
> ...    print 'Hello'
>
> It works for empty numpy arrays:
>
>>> a = np.array(seq)
>>> if not a:
> ...     print 'Hello"
> Hello
>
> but if 'a' is non-empty it raises an exception:
>
>>> a = np.array([1,2])
>>> if not a:
> ...     print 'Hello"
> ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>
> One solution is to test lengths:
>
>>> if len(seq) > 0:
> ....    ...
>>> if len(a) > 0:
> ...     ...
>
> but for None it fails again:
>
>>> opt = None
>>> if len(opt):
> ...
> TypeError: object of type 'NoneType' has no len()
>
> even worse we can not test for None, because it will fail if someone accidentally wraps None in an array:
>
>>> a = np.array(opt)
>>> if opt is not None:
> ...      print 'hello'
> hello
>
> Although this behaviour is expected, it may be very confusing and it easily leads to errors. Even worse it adds unnecessary complexity in the code, because arrays, lists and None have to be handled differently.
>
> I hoped the I managed to explain the problem well. Is there a recommended way to test for empty arrays?

[~]
|5> x = np.zeros([0])

[~]
|6> x
array([], dtype=float64)

[~]
|7> x.size == 0
True


Note that checking for len(x) will fail for some empty arrays:

[~]
|8> x = np.zeros([10, 0])

[~]
|9> x.size == 0
True

[~]
|10> len(x)
10

There is no way to test all of the cases (empty sequence, empty array,
None) in the same way. Usually, it's a bad idea to conflate the three.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco



More information about the NumPy-Discussion mailing list