python-peps/peps/pep-0424.rst

95 lines
2.9 KiB
ReStructuredText
Raw Permalink Normal View History

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
Created: 14-Jul-2012
2012-07-14 18:08:03 -04:00
Python-Version: 3.4
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
========
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
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,
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
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).
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)::
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.
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-10-06 07:01:10 -04:00
try:
return len(obj)
2012-10-06 07:01:10 -04:00
except TypeError:
try:
2012-10-06 07:01:10 -04:00
get_hint = type(obj).__length_hint__
except AttributeError:
return default
2012-10-06 07:01:10 -04:00
try:
hint = get_hint(obj)
except TypeError:
return default
if hint is NotImplemented:
return default
if not isinstance(hint, int):
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-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: