[Python-Dev] PEP 0424: A method for exposing a length hint
Alexandre Zani
alexandre.zani at gmail.com
Sun Jul 15 17:38:20 CEST 2012
On Sun, Jul 15, 2012 at 8:08 AM, Mark Shannon <mark at hotpy.org> wrote:
> Brett Cannon wrote:
>
>>
>>
>> On Sun, Jul 15, 2012 at 10:39 AM, Mark Shannon <mark at hotpy.org
>> <mailto:mark at hotpy.org>> wrote:
>>
>> Nick Coghlan wrote:
>>
>> Right, I agree on the value in being able to return something to
>> say "this cannot be converted to a concrete container".
>>
>> I still haven't seen a use case where the appropriate response
>> to "I don't know" differs from the appropriate response to a
>> hint of zero - that is, you don't preallocate, you just start
>> iterating.
>>
>>
>> There seem to be 5 possible classes values of __length_hint__ that an
>> iterator object can provide:
>>
>> 1. Don't implement it at all.
>>
>> 2. Implement __length_hint__() but don't want to return any value.
>> Either raise an exception (TypeError) -- As suggested in the PEP.
>> or return NotImplemented -- my preferred option.
>>
>> 3. Return a "don't know" value:
>> Returning 0 would be fine for this, but the VM might want to
>> respond
>> differently to "don't know" and 0.
>> __length_hint__() == 0 container should be
>> minimum size.
>> __length_hint__() == "unknown" container starts at
>> default size.
>>
>>
>> 4. Infinite iterator:
>> Could return float('inf'), but given this is a "hint" then
>> returning sys.maxsize or sys.maxsize + 1 might be OK.
>> Alternatively raise an OverflowError
>>
>>
>> I am really having a hard time differentiating infinity with "I don't
>> know" since they are both accurate from the point of view of __length_hint__
>> and its typical purpose of allocation. You have no clue how many values will
>> be grabbed from an infinite iterator, so it's the same as just not knowing
>> upfront how long the iterator will be, infinite or not, and thus not worth
>> distinguishing.
>>
>>
>> 5. A meaningful length. No problem :)
>>
>> Also, what are the allowable return types?
>>
>> 1. int only
>> 2. Any number (ie any type with a __int__() method)?
>> 3. Or any integer-like object (ie a type with a __index__() method)?
>>
>> My suggestion:
>>
>> a) Don't want to return any value or "don't know": return
>> NotImplemented
>> b) For infinite iterators: raise an OverflowError
>> c) All other cases: return an int or a type with a __index__() method.
>>
>>
>> I'm fine with (a), drop (b), and for (c) use what we allow for __len__()
>> since, as Nick's operator.length_hint pseudo-code suggests, people will call
>> this as a fallback if __len__ isn't defined.
>
>
> So how does an iterator express infinite length?
>
> What should happen if I am silly enough to do this:
>>>> list(itertools.count())
>
> This will fail; it should fail quickly.
>
>
> Cheers,
> Mark.
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/alexandre.zani%40gmail.com
The PEP so far says: "It may raise a ``TypeError`` if a specific
instance cannot have
its length estimated." In many ways, "I don't know" is the same as
this "specific instance cannot have its length estimated". Why not
just raise a TypeError?
Also, regarding the code Nick posted above, I'm a little concerned
about calling len as the first thing to try. That means that if I
implement both __len__ and __len_hint__ (perhaps because __len__ is
very expensive) __len_hint__ will never be used. It's relatively easy
to say:
try:
hint = len_hint(l)
except TypeError:
hint = len(l)
More information about the Python-Dev
mailing list