mirror of https://github.com/python/cpython.git
Make collections' doctests executable.
(The <BLANKLINE>s will be stripped from presentation output.)
This commit is contained in:
parent
3dd57815b2
commit
4c8bbe69e5
|
@ -7,9 +7,14 @@
|
||||||
.. moduleauthor:: Raymond Hettinger <python@rcn.com>
|
.. moduleauthor:: Raymond Hettinger <python@rcn.com>
|
||||||
.. sectionauthor:: Raymond Hettinger <python@rcn.com>
|
.. sectionauthor:: Raymond Hettinger <python@rcn.com>
|
||||||
|
|
||||||
|
|
||||||
.. versionadded:: 2.4
|
.. versionadded:: 2.4
|
||||||
|
|
||||||
|
.. testsetup:: *
|
||||||
|
|
||||||
|
from collections import *
|
||||||
|
import itertools
|
||||||
|
__name__ = '<doctest>'
|
||||||
|
|
||||||
This module implements high-performance container datatypes. Currently,
|
This module implements high-performance container datatypes. Currently,
|
||||||
there are two datatypes, :class:`deque` and :class:`defaultdict`, and
|
there are two datatypes, :class:`deque` and :class:`defaultdict`, and
|
||||||
one datatype factory function, :func:`namedtuple`.
|
one datatype factory function, :func:`namedtuple`.
|
||||||
|
@ -235,7 +240,9 @@ In addition to the above, deques support iteration, pickling, ``len(d)``,
|
||||||
``reversed(d)``, ``copy.copy(d)``, ``copy.deepcopy(d)``, membership testing with
|
``reversed(d)``, ``copy.copy(d)``, ``copy.deepcopy(d)``, membership testing with
|
||||||
the :keyword:`in` operator, and subscript references such as ``d[-1]``.
|
the :keyword:`in` operator, and subscript references such as ``d[-1]``.
|
||||||
|
|
||||||
Example::
|
Example:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
>>> from collections import deque
|
>>> from collections import deque
|
||||||
>>> d = deque('ghi') # make a new deque with three items
|
>>> d = deque('ghi') # make a new deque with three items
|
||||||
|
@ -319,7 +326,7 @@ a reduction function, and calling :meth:`append` to add the result back to the
|
||||||
deque.
|
deque.
|
||||||
|
|
||||||
For example, building a balanced binary tree of nested lists entails reducing
|
For example, building a balanced binary tree of nested lists entails reducing
|
||||||
two adjacent nodes into one by grouping them in a list::
|
two adjacent nodes into one by grouping them in a list:
|
||||||
|
|
||||||
>>> def maketree(iterable):
|
>>> def maketree(iterable):
|
||||||
... d = deque(iterable)
|
... d = deque(iterable)
|
||||||
|
@ -393,7 +400,7 @@ standard :class:`dict` operations:
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Using :class:`list` as the :attr:`default_factory`, it is easy to group a
|
Using :class:`list` as the :attr:`default_factory`, it is easy to group a
|
||||||
sequence of key-value pairs into a dictionary of lists::
|
sequence of key-value pairs into a dictionary of lists:
|
||||||
|
|
||||||
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
|
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
|
||||||
>>> d = defaultdict(list)
|
>>> d = defaultdict(list)
|
||||||
|
@ -409,7 +416,7 @@ function which returns an empty :class:`list`. The :meth:`list.append`
|
||||||
operation then attaches the value to the new list. When keys are encountered
|
operation then attaches the value to the new list. When keys are encountered
|
||||||
again, the look-up proceeds normally (returning the list for that key) and the
|
again, the look-up proceeds normally (returning the list for that key) and the
|
||||||
:meth:`list.append` operation adds another value to the list. This technique is
|
:meth:`list.append` operation adds another value to the list. This technique is
|
||||||
simpler and faster than an equivalent technique using :meth:`dict.setdefault`::
|
simpler and faster than an equivalent technique using :meth:`dict.setdefault`:
|
||||||
|
|
||||||
>>> d = {}
|
>>> d = {}
|
||||||
>>> for k, v in s:
|
>>> for k, v in s:
|
||||||
|
@ -420,7 +427,7 @@ simpler and faster than an equivalent technique using :meth:`dict.setdefault`::
|
||||||
|
|
||||||
Setting the :attr:`default_factory` to :class:`int` makes the
|
Setting the :attr:`default_factory` to :class:`int` makes the
|
||||||
:class:`defaultdict` useful for counting (like a bag or multiset in other
|
:class:`defaultdict` useful for counting (like a bag or multiset in other
|
||||||
languages)::
|
languages):
|
||||||
|
|
||||||
>>> s = 'mississippi'
|
>>> s = 'mississippi'
|
||||||
>>> d = defaultdict(int)
|
>>> d = defaultdict(int)
|
||||||
|
@ -437,7 +444,7 @@ zero. The increment operation then builds up the count for each letter.
|
||||||
The function :func:`int` which always returns zero is just a special case of
|
The function :func:`int` which always returns zero is just a special case of
|
||||||
constant functions. A faster and more flexible way to create constant functions
|
constant functions. A faster and more flexible way to create constant functions
|
||||||
is to use :func:`itertools.repeat` which can supply any constant value (not just
|
is to use :func:`itertools.repeat` which can supply any constant value (not just
|
||||||
zero)::
|
zero):
|
||||||
|
|
||||||
>>> def constant_factory(value):
|
>>> def constant_factory(value):
|
||||||
... return itertools.repeat(value).next
|
... return itertools.repeat(value).next
|
||||||
|
@ -447,7 +454,7 @@ zero)::
|
||||||
'John ran to <missing>'
|
'John ran to <missing>'
|
||||||
|
|
||||||
Setting the :attr:`default_factory` to :class:`set` makes the
|
Setting the :attr:`default_factory` to :class:`set` makes the
|
||||||
:class:`defaultdict` useful for building a dictionary of sets::
|
:class:`defaultdict` useful for building a dictionary of sets:
|
||||||
|
|
||||||
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
|
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
|
||||||
>>> d = defaultdict(set)
|
>>> d = defaultdict(set)
|
||||||
|
@ -492,41 +499,44 @@ they add the ability to access fields by name instead of position index.
|
||||||
|
|
||||||
.. versionadded:: 2.6
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
Example::
|
Example:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
:options: +NORMALIZE_WHITESPACE
|
||||||
|
|
||||||
>>> Point = namedtuple('Point', 'x y', verbose=True)
|
>>> Point = namedtuple('Point', 'x y', verbose=True)
|
||||||
class Point(tuple):
|
class Point(tuple):
|
||||||
'Point(x, y)'
|
'Point(x, y)'
|
||||||
|
<BLANKLINE>
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
<BLANKLINE>
|
||||||
_fields = ('x', 'y')
|
_fields = ('x', 'y')
|
||||||
|
<BLANKLINE>
|
||||||
def __new__(cls, x, y):
|
def __new__(cls, x, y):
|
||||||
return tuple.__new__(cls, (x, y))
|
return tuple.__new__(cls, (x, y))
|
||||||
|
<BLANKLINE>
|
||||||
@classmethod
|
@classmethod
|
||||||
def _make(cls, iterable):
|
def _make(cls, iterable, new=tuple.__new__, len=len):
|
||||||
'Make a new Point object from a sequence or iterable'
|
'Make a new Point object from a sequence or iterable'
|
||||||
result = tuple.__new__(cls, iterable)
|
result = new(cls, iterable)
|
||||||
if len(result) != 2:
|
if len(result) != 2:
|
||||||
raise TypeError('Expected 2 arguments, got %d' % len(result))
|
raise TypeError('Expected 2 arguments, got %d' % len(result))
|
||||||
return result
|
return result
|
||||||
|
<BLANKLINE>
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Point(x=%r, y=%r)' % self
|
return 'Point(x=%r, y=%r)' % self
|
||||||
|
<BLANKLINE>
|
||||||
def _asdict(t):
|
def _asdict(t):
|
||||||
'Return a new dict which maps field names to their values'
|
'Return a new dict which maps field names to their values'
|
||||||
return {'x': t[0], 'y': t[1]}
|
return {'x': t[0], 'y': t[1]}
|
||||||
|
<BLANKLINE>
|
||||||
def _replace(self, **kwds):
|
def _replace(self, **kwds):
|
||||||
'Return a new Point object replacing specified fields with new values'
|
'Return a new Point object replacing specified fields with new values'
|
||||||
result = self._make(map(kwds.pop, ('x', 'y'), self))
|
result = self._make(map(kwds.pop, ('x', 'y'), self))
|
||||||
if kwds:
|
if kwds:
|
||||||
raise ValueError('Got unexpected field names: %r' % kwds.keys())
|
raise ValueError('Got unexpected field names: %r' % kwds.keys())
|
||||||
return result
|
return result
|
||||||
|
<BLANKLINE>
|
||||||
x = property(itemgetter(0))
|
x = property(itemgetter(0))
|
||||||
y = property(itemgetter(1))
|
y = property(itemgetter(1))
|
||||||
|
|
||||||
|
@ -565,7 +575,7 @@ field names, the method and attribute names start with an underscore.
|
||||||
|
|
||||||
Class method that makes a new instance from an existing sequence or iterable.
|
Class method that makes a new instance from an existing sequence or iterable.
|
||||||
|
|
||||||
::
|
.. doctest::
|
||||||
|
|
||||||
>>> t = [11, 22]
|
>>> t = [11, 22]
|
||||||
>>> Point._make(t)
|
>>> Point._make(t)
|
||||||
|
@ -573,16 +583,15 @@ field names, the method and attribute names start with an underscore.
|
||||||
|
|
||||||
.. method:: somenamedtuple._asdict()
|
.. method:: somenamedtuple._asdict()
|
||||||
|
|
||||||
Return a new dict which maps field names to their corresponding values:
|
Return a new dict which maps field names to their corresponding values::
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
>>> p._asdict()
|
>>> p._asdict()
|
||||||
{'x': 11, 'y': 22}
|
{'x': 11, 'y': 22}
|
||||||
|
|
||||||
.. method:: somenamedtuple._replace(kwargs)
|
.. method:: somenamedtuple._replace(kwargs)
|
||||||
|
|
||||||
Return a new instance of the named tuple replacing specified fields with new values:
|
Return a new instance of the named tuple replacing specified fields with new
|
||||||
|
values:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -598,7 +607,7 @@ field names, the method and attribute names start with an underscore.
|
||||||
Tuple of strings listing the field names. Useful for introspection
|
Tuple of strings listing the field names. Useful for introspection
|
||||||
and for creating new named tuple types from existing named tuples.
|
and for creating new named tuple types from existing named tuples.
|
||||||
|
|
||||||
::
|
.. doctest::
|
||||||
|
|
||||||
>>> p._fields # view the field names
|
>>> p._fields # view the field names
|
||||||
('x', 'y')
|
('x', 'y')
|
||||||
|
@ -609,12 +618,12 @@ field names, the method and attribute names start with an underscore.
|
||||||
Pixel(x=11, y=22, red=128, green=255, blue=0)
|
Pixel(x=11, y=22, red=128, green=255, blue=0)
|
||||||
|
|
||||||
To retrieve a field whose name is stored in a string, use the :func:`getattr`
|
To retrieve a field whose name is stored in a string, use the :func:`getattr`
|
||||||
function::
|
function:
|
||||||
|
|
||||||
>>> getattr(p, 'x')
|
>>> getattr(p, 'x')
|
||||||
11
|
11
|
||||||
|
|
||||||
To convert a dictionary to a named tuple, use the double-star-operator [#]_::
|
To convert a dictionary to a named tuple, use the double-star-operator [#]_:
|
||||||
|
|
||||||
>>> d = {'x': 11, 'y': 22}
|
>>> d = {'x': 11, 'y': 22}
|
||||||
>>> Point(**d)
|
>>> Point(**d)
|
||||||
|
@ -622,7 +631,7 @@ To convert a dictionary to a named tuple, use the double-star-operator [#]_::
|
||||||
|
|
||||||
Since a named tuple is a regular Python class, it is easy to add or change
|
Since a named tuple is a regular Python class, it is easy to add or change
|
||||||
functionality with a subclass. Here is how to add a calculated field and
|
functionality with a subclass. Here is how to add a calculated field and
|
||||||
a fixed-width print format::
|
a fixed-width print format:
|
||||||
|
|
||||||
>>> class Point(namedtuple('Point', 'x y')):
|
>>> class Point(namedtuple('Point', 'x y')):
|
||||||
... __slots__ = ()
|
... __slots__ = ()
|
||||||
|
@ -634,7 +643,6 @@ a fixed-width print format::
|
||||||
|
|
||||||
>>> for p in Point(3, 4), Point(14, 5/7.):
|
>>> for p in Point(3, 4), Point(14, 5/7.):
|
||||||
... print p
|
... print p
|
||||||
|
|
||||||
Point: x= 3.000 y= 4.000 hypot= 5.000
|
Point: x= 3.000 y= 4.000 hypot= 5.000
|
||||||
Point: x=14.000 y= 0.714 hypot=14.018
|
Point: x=14.000 y= 0.714 hypot=14.018
|
||||||
|
|
||||||
|
@ -642,12 +650,12 @@ The subclass shown above sets ``__slots__`` to an empty tuple. This keeps
|
||||||
keep memory requirements low by preventing the creation of instance dictionaries.
|
keep memory requirements low by preventing the creation of instance dictionaries.
|
||||||
|
|
||||||
Subclassing is not useful for adding new, stored fields. Instead, simply
|
Subclassing is not useful for adding new, stored fields. Instead, simply
|
||||||
create a new named tuple type from the :attr:`_fields` attribute::
|
create a new named tuple type from the :attr:`_fields` attribute:
|
||||||
|
|
||||||
>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))
|
>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))
|
||||||
|
|
||||||
Default values can be implemented by using :meth:`_replace` to
|
Default values can be implemented by using :meth:`_replace` to
|
||||||
customize a prototype instance::
|
customize a prototype instance:
|
||||||
|
|
||||||
>>> Account = namedtuple('Account', 'owner balance transaction_count')
|
>>> Account = namedtuple('Account', 'owner balance transaction_count')
|
||||||
>>> default_account = Account('<owner name>', 0.0, 0)
|
>>> default_account = Account('<owner name>', 0.0, 0)
|
||||||
|
|
Loading…
Reference in New Issue