[Python-Dev] Clean way in python to test for None, empty, scalar, and list/ndarray? A prayer to the gods of Python

Robert Kern robert.kern at gmail.com
Sat Jun 15 00:53:53 CEST 2013


On 2013-06-14 23:31, Robert Kern wrote:
> On 2013-06-14 21:55, R. David Murray wrote:
>> On Fri, 14 Jun 2013 21:12:00 +0200, Martin Schultz <maschu09 at gmail.com> wrote:
>>> 2. Testing for empty lists or empty ndarrays:
>>>
>>>   In principle, `len(x) == 0` will do the trick. **BUT** there are several
>>> caveats here:
>>>     - `len(scalar)` raises a TypeError, so you will have to use try and
>>> except or find some other way of testing for a scalar value
>>>     - `len(numpy.array(0))` (i.e. a scalar coded as numpy array) also raises
>>> a TypeError ("unsized object")
>>>     - `len([[]])` returns a length of 1, which is somehow understandable,
>>> but - I would argue - perhaps not what one might expect initially
>>>
>>>   Alternatively, numpy arrays have a size attribute, and
>>> `numpy.array([]).size`, `numpy.array(8.).size`, and
>>> `numpy.array([8.]).size` all return what you would expect. And even
>>> `numpy.array([[]]).size` gives you 0. Now, if I could convert everything to
>>> a numpy array, this might work. But have you ever tried to assign a list of
>>> mixed data types to a numpy array? `numpy.array(["a",1,[2,3],(888,9)])`
>>> will fail, even though the list inside is perfectly fine as a list.
>>
>> In general you test whether nor not something is empty in Python by
>> testing its truth value.  Empty things are False.  Numpy seems to
>> follow this using size, from the limited examples you have given
>>
>>     >>> bool(numpy.array([[]])
>>     False
>>     >>> bool(numpy.array([[1]])
>>     True
>
> numpy does not do so. Empty arrays are extremely rare and testing for them rarer
> (rarer still is testing for emptiness not knowing if it is an array or some
> other sequence). What people usually want from bool(some_array) is either
> some_array.all() or some_array.any(). In the face of this ambiguity, numpy
> refuses the temptation to guess and raises an exception explaining matters.

Actually, that's a bit of a lie. In the empty case and the one-element case, we 
do return a bool, False for empty and bool(element) for whatever that one 
element is. Anything else raises the exception since we don't know whether it is 
all() or any() that was desired.

-- 
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 Python-Dev mailing list