[Numpy-discussion] numpy all unexpected result (generator)
Tue Jan 31 08:33:55 CST 2012
Dag Sverre Seljebotn wrote:
> On 01/31/2012 03:07 PM, Robert Kern wrote:
>> On Tue, Jan 31, 2012 at 13:26, Neal Becker<firstname.lastname@example.org> wrote:
>>> I was just bitten by this unexpected behavior:
>>> In : all ([i> 0 for i in xrange (10)])
>>> Out: False
>>> In : all (i> 0 for i in xrange (10))
>>> Out: True
>>> Turns out:
>>> In : all is numpy.all
>>> Out: True
>>> So numpy.all doesn't seem to do what I would expect when given a generator.
>> Expected behavior. numpy.all(), like nearly all numpy functions,
>> converts the input to an array using numpy.asarray(). numpy.asarray()
>> knows nothing special about generators and other iterables that are
>> not sequences, so it thinks it's a single scalar object. This scalar
>> object happens to have a __nonzero__() method that returns True like
>> most Python objects that don't override this.
>> In order to use generic iterators that are not sequences, you need to
>> explicitly use numpy.fromiter() to convert them to ndarrays. asarray()
>> and array() can't do it in general because they need to autodiscover
>> the shape and dtype all at the same time.
> Perhaps np.asarray could specifically check for a generator argument and
> raise an exception? I imagine that would save people some time when
> running into this...
> If you really want
> In : x = np.asarray(None)
> In : x[()] = (i for i in range(10))
> In : x
> Out: array(<generator object <genexpr> at 0x4553fa0>, dtype=object)
> ...then one can type it out?
The reason it surprised me, is that python 'all' doesn't behave as numpy 'all'
in this respect - and using ipython, I didn't even notice that 'all' was
numpy.all rather than standard python all. All in all, rather unfortunate :)
More information about the NumPy-Discussion