1

Can someone explain the logic behind the output of the following script?

import numpy
if(numpy.dtype(numpy.float64):
    print "Expected"
else:
    print "Surprise!!!!"

Especially considering:

import numpy
if(object):
    print "Expected!"
else:
    print "Surprise"

Thanks :)

3
  • possible duplicate of Why is numpy.dtype('float64') special? Commented Mar 22, 2014 at 9:24
  • @StephenDiehl that question is about why dtype('float64') == None; this one is about why bool(dtype('float64')) == False. Commented Mar 22, 2014 at 9:29
  • 1
    I do not believe it is. "Why is numpy.dtype('float64') special?" is answered, but the answer does not apply in this case. So related: absolutely; but not a duplicate. Commented Mar 22, 2014 at 9:30

1 Answer 1

3

np.dtype does not define __nonzero__, but it does define __len__. As per the documentation, this means when you use it in a boolean context, it will evaluate to True if __len__ returns non-zero. But it always returns zero, regardless of what type you pass in:

>>> bool(np.dtype(int))
False
>>> bool(np.dtype(float))
False
>>> bool(np.dtype(np.int8))
False

On the other hand, a compound data type does return nonzero, thus True:

>>> bool(np.dtype([('foo', int)]))
True

You might then ask why the "length" of a simple dtype is zero, when the length of a compound one with a single element is one. I imagine that's something about dimensionality: an array with a simple dtype and one-dimensional size is itself one-dimensional, but an array with a compound dtype and one-dimensional size may be thought of as two-dimensional, regardless of how many elements are in the compound dtype.

Sign up to request clarification or add additional context in comments.

4 Comments

Strange, especially since 0-dimensional arrays properly raise TypeError for len. I suspect these parts of the dtype API just didn't get much attention.
Thanks! That explains it. I would consider that a bug in numpy. easily fixed by defining nonzero in numpy.dtype?
Your supposition about compound dtypes seems to be slightly off: len(np.dtype([('foo', int), ('bar', int)])) is 2. __getitem__ also exists, and behaves as you would expect. @TroelsBlum this isn't necessarily a bug. It seems dtypes follow the sequence protocol, with simple dtypes being an empty sequence - and empty sequences are conventionally False.
@lvc: I know a two-element compound dtype has len==2. That makes sense. It also has dimension 1, conceptually. My point is that a simple dtype has dimension 0, so a 1D array of floats is 1D, but a 1D array of dtype([('foo', float)]) can be considered 2D.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.