2012-07-14 18:07:48 -04:00
|
|
|
|
PEP: 424
|
|
|
|
|
Title: A method for exposing a length hint
|
|
|
|
|
Version: $Revision$
|
2012-10-06 08:18:33 -04:00
|
|
|
|
Last-Modified: $Date$
|
2012-07-14 18:07:48 -04:00
|
|
|
|
Author: Alex Gaynor <alex.gaynor@gmail.com>
|
2012-10-06 08:18:33 -04:00
|
|
|
|
Status: Final
|
2012-07-14 18:07:48 -04:00
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
2021-02-09 11:54:26 -05:00
|
|
|
|
Created: 14-Jul-2012
|
2012-07-14 18:08:03 -04:00
|
|
|
|
Python-Version: 3.4
|
2022-03-09 11:04:44 -05:00
|
|
|
|
Post-History: `15-Jul-2012 <https://mail.python.org/pipermail/python-dev/2012-July/120920.html>`__
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
2012-07-30 13:12:18 -04:00
|
|
|
|
CPython currently defines a ``__length_hint__`` method on several
|
2012-10-06 07:04:01 -04:00
|
|
|
|
types, such as various iterators. This method is then used by various
|
2012-07-30 13:12:18 -04:00
|
|
|
|
other functions (such as ``list``) to presize lists based on the
|
2012-10-06 07:04:01 -04:00
|
|
|
|
estimate returned by ``__length_hint__``. Types which are not sized,
|
2012-07-30 13:12:18 -04:00
|
|
|
|
and thus should not define ``__len__``, can then define
|
|
|
|
|
``__length_hint__``, to allow estimating or computing a size (such as
|
|
|
|
|
many iterators).
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
2012-07-30 13:12:18 -04:00
|
|
|
|
Specification
|
|
|
|
|
=============
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
2012-10-06 07:04:01 -04:00
|
|
|
|
This PEP formally documents ``__length_hint__`` for other interpreters
|
|
|
|
|
and non-standard-library Python modules to implement.
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
2012-10-06 07:04:01 -04:00
|
|
|
|
``__length_hint__`` must return an integer (else a ``TypeError`` is
|
|
|
|
|
raised) or ``NotImplemented``, and is not required to be accurate. It
|
|
|
|
|
may return a value that is either larger or smaller than the actual
|
|
|
|
|
size of the container. A return value of ``NotImplemented`` indicates
|
|
|
|
|
that there is no finite length estimate. It may not return a negative
|
|
|
|
|
value (else a ValueError is raised).
|
2012-07-16 23:00:55 -04:00
|
|
|
|
|
2012-07-30 13:12:18 -04:00
|
|
|
|
In addition, a new function ``operator.length_hint`` hint is added,
|
2012-10-06 07:04:01 -04:00
|
|
|
|
with the following semantics (which define how ``__length_hint__``
|
|
|
|
|
should be used)::
|
2012-07-16 23:00:55 -04:00
|
|
|
|
|
2012-07-30 13:12:18 -04:00
|
|
|
|
def length_hint(obj, default=0):
|
|
|
|
|
"""Return an estimate of the number of items in obj.
|
|
|
|
|
|
|
|
|
|
This is useful for presizing containers when building from an
|
|
|
|
|
iterable.
|
2012-07-16 23:00:55 -04:00
|
|
|
|
|
2012-07-30 13:12:18 -04:00
|
|
|
|
If the object supports len(), the result will be
|
|
|
|
|
exact. Otherwise, it may over- or under-estimate by an
|
|
|
|
|
arbitrary amount. The result will be an integer >= 0.
|
2012-07-16 23:00:55 -04:00
|
|
|
|
"""
|
2012-10-06 07:01:10 -04:00
|
|
|
|
try:
|
2012-07-16 23:00:55 -04:00
|
|
|
|
return len(obj)
|
2012-10-06 07:01:10 -04:00
|
|
|
|
except TypeError:
|
2012-07-16 23:00:55 -04:00
|
|
|
|
try:
|
2012-10-06 07:01:10 -04:00
|
|
|
|
get_hint = type(obj).__length_hint__
|
2012-07-16 23:00:55 -04:00
|
|
|
|
except AttributeError:
|
|
|
|
|
return default
|
2012-10-06 07:01:10 -04:00
|
|
|
|
try:
|
|
|
|
|
hint = get_hint(obj)
|
|
|
|
|
except TypeError:
|
|
|
|
|
return default
|
2012-07-16 23:00:55 -04:00
|
|
|
|
if hint is NotImplemented:
|
|
|
|
|
return default
|
|
|
|
|
if not isinstance(hint, int):
|
2012-07-30 13:12:18 -04:00
|
|
|
|
raise TypeError("Length hint must be an integer, not %r" %
|
|
|
|
|
type(hint))
|
2012-10-06 07:01:10 -04:00
|
|
|
|
if hint < 0:
|
|
|
|
|
raise ValueError("__length_hint__() should return >= 0")
|
|
|
|
|
return hint
|
2012-07-16 23:00:55 -04:00
|
|
|
|
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
2012-10-06 07:04:01 -04:00
|
|
|
|
Being able to pre-allocate lists based on the expected size, as
|
|
|
|
|
estimated by ``__length_hint__``, can be a significant optimization.
|
|
|
|
|
CPython has been observed to run some code faster than PyPy, purely
|
|
|
|
|
because of this optimization being present.
|
2012-07-14 18:07:48 -04:00
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed into the public domain.
|
|
|
|
|
|
2012-10-06 06:23:21 -04:00
|
|
|
|
|
|
|
|
|
|
2012-07-14 18:07:48 -04:00
|
|
|
|
..
|
2012-10-06 06:23:21 -04:00
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|