diff options
Diffstat (limited to 'Doc/library/collections.rst')
-rw-r--r-- | Doc/library/collections.rst | 125 |
1 files changed, 71 insertions, 54 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 274ca15..ba3ce31 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -10,7 +10,7 @@ This module implements high-performance container datatypes. Currently, there are two datatypes, :class:`deque` and :class:`defaultdict`, and -one datatype factory function, :func:`NamedTuple`. Python already +one datatype factory function, :func:`named_tuple`. Python already includes built-in containers, :class:`dict`, :class:`list`, :class:`set`, and :class:`tuple`. In addition, the optional :mod:`bsddb` module has a :meth:`bsddb.btopen` method that can be used to create in-memory @@ -75,7 +75,7 @@ particular functionality, for example:: ---------------------- -.. class:: deque([iterable]) +.. class:: deque([iterable[, maxlen]]) Returns a new deque object initialized left-to-right (using :meth:`append`) with data from *iterable*. If *iterable* is not specified, the new deque is empty. @@ -91,6 +91,17 @@ particular functionality, for example:: position of the underlying data representation. + If *maxlen* is not specified or is *None*, deques may grow to an + arbitrary length. Otherwise, the deque is bounded to the specified maximum + length. Once a bounded length deque is full, when new items are added, a + corresponding number of items are discarded from the opposite end. Bounded + length deques provide functionality similar to the ``tail`` filter in + Unix. They are also useful for tracking transactions and other pools of data + where only the most recent activity is of interest. + + .. versionchanged:: 2.6 + Added *maxlen* + Deque objects support the following methods: .. method:: deque.append(x) @@ -205,8 +216,8 @@ Example:: .. _deque-recipes: -Recipes -^^^^^^^ +:class:`deque` Recipes +^^^^^^^^^^^^^^^^^^^^^^ This section shows various approaches to working with deques. @@ -223,42 +234,14 @@ To implement :class:`deque` slicing, use a similar approach applying :meth:`rotate` to bring a target element to the left side of the deque. Remove old entries with :meth:`popleft`, add new entries with :meth:`extend`, and then reverse the rotation. - With minor variations on that approach, it is easy to implement Forth style stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``, ``rot``, and ``roll``. -A roundrobin task server can be built from a :class:`deque` using -:meth:`popleft` to select the current task and :meth:`append` to add it back to -the tasklist if the input stream is not exhausted:: - - >>> def roundrobin(*iterables): - ... pending = deque(iter(i) for i in iterables) - ... while pending: - ... task = pending.popleft() - ... try: - ... yield next(task) - ... except StopIteration: - ... continue - ... pending.append(task) - ... - >>> for value in roundrobin('abc', 'd', 'efgh'): - ... print(value) - - a - d - e - b - f - c - g - h - - Multi-pass data reduction algorithms can be succinctly expressed and efficiently coded by extracting elements with multiple calls to :meth:`popleft`, applying -the reduction function, and calling :meth:`append` to add the result back to the -queue. +a reduction function, and calling :meth:`append` to add the result back to the +deque. For example, building a balanced binary tree of nested lists entails reducing two adjacent nodes into one by grouping them in a list:: @@ -273,7 +256,12 @@ two adjacent nodes into one by grouping them in a list:: >>> print(maketree('abcdefgh')) [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]] +Bounded length deques provide functionality similar to the ``tail`` filter +in Unix:: + def tail(filename, n=10): + 'Return the last n lines of a file' + return deque(open(filename), n) .. _defaultdict-objects: @@ -395,14 +383,14 @@ Setting the :attr:`default_factory` to :class:`set` makes the .. _named-tuple-factory: -:func:`NamedTuple` Factory Function for Tuples with Named Fields ----------------------------------------------------------------- +:func:`named_tuple` Factory Function for Tuples with Named Fields +----------------------------------------------------------------- Named tuples assign meaning to each position in a tuple and allow for more readable, self-documenting code. They can be used wherever regular tuples are used, and they add the ability to access fields by name instead of position index. -.. function:: NamedTuple(typename, fieldnames, [verbose]) +.. function:: named_tuple(typename, fieldnames, [verbose]) Returns a new tuple subclass named *typename*. The new subclass is used to create tuple-like objects that have fields accessable by attribute lookup as @@ -410,17 +398,24 @@ they add the ability to access fields by name instead of position index. helpful docstring (with typename and fieldnames) and a helpful :meth:`__repr__` method which lists the tuple contents in a ``name=value`` format. - The *fieldnames* are specified in a single string with each fieldname separated by - a space and/or comma. Any valid Python identifier may be used for a fieldname. + The *fieldnames* are a single string with each fieldname separated by whitespace + and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames* + can be specified as a list of strings (such as ['x', 'y']). + + Any valid Python identifier may be used for a fieldname except for names + starting and ending with double underscores. Valid identifiers consist of + letters, digits, and underscores but do not start with a digit and cannot be + a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*, + or *raise*. If *verbose* is true, will print the class definition. - *NamedTuple* instances do not have per-instance dictionaries, so they are + Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples. Example:: - >>> Point = NamedTuple('Point', 'x y', True) + >>> Point = named_tuple('Point', 'x y', verbose=True) class Point(tuple): 'Point(x, y)' __slots__ = () @@ -429,6 +424,9 @@ Example:: return tuple.__new__(cls, (x, y)) def __repr__(self): return 'Point(x=%r, y=%r)' % self + def __asdict__(self): + 'Return a new dict mapping field names to their values' + return dict(zip(('x', 'y'), self)) def __replace__(self, field, value): 'Return a new Point object replacing one field with a new value' return Point(**dict(zip(('x', 'y'), self) + [(field, value)])) @@ -449,23 +447,46 @@ Example:: Named tuples are especially useful for assigning field names to result tuples returned by the :mod:`csv` or :mod:`sqlite3` modules:: + EmployeeRecord = named_tuple('EmployeeRecord', 'name, age, title, department, paygrade') + from itertools import starmap import csv - EmployeeRecord = NamedTuple('EmployeeRecord', 'name age title department paygrade') for record in starmap(EmployeeRecord, csv.reader(open("employees.csv", "rb"))): print(emp.name, emp.title) -When casting a single record to a *NamedTuple*, use the star-operator [#]_ to unpack + import sqlite3 + conn = sqlite3.connect('/companydata') + cursor = conn.cursor() + cursor.execute('SELECT name, age, title, department, paygrade FROM employees') + for emp in starmap(EmployeeRecord, cursor.fetchall()): + print emp.name, emp.title + +When casting a single record to a named tuple, use the star-operator [#]_ to unpack the values:: >>> t = [11, 22] >>> Point(*t) # the star-operator unpacks any iterable object Point(x=11, y=22) +When casting a dictionary to a named tuple, use the double-star-operator:: + + >>> d = {'x': 11, 'y': 22} + >>> Point(**d) + Point(x=11, y=22) + In addition to the methods inherited from tuples, named tuples support -an additonal method and an informational read-only attribute. +two additonal methods and a read-only attribute. + +.. method:: somenamedtuple.__asdict__() + + Return a new dict which maps field names to their corresponding values: + +:: -.. method:: somenamedtuple.replace(field, value) + >>> p.__asdict__() + {'x': 11, 'y': 22} + +.. method:: somenamedtuple.__replace__(field, value) Return a new instance of the named tuple replacing the named *field* with a new *value*: @@ -480,20 +501,16 @@ an additonal method and an informational read-only attribute. .. attribute:: somenamedtuple.__fields__ - Return a tuple of strings listing the field names. This is useful for introspection, - for converting a named tuple instance to a dictionary, and for combining named tuple - types to create new named tuple types: + Return a tuple of strings listing the field names. This is useful for introspection + and for creating new named tuple types from existing named tuples. :: - >>> p.__fields__ # view the field names + >>> p.__fields__ # view the field names ('x', 'y') - >>> dict(zip(p.__fields__, p)) # convert to a dictionary - {'y': 22, 'x': 11} - >>> Color = NamedTuple('Color', 'red green blue') - >>> pixel_fields = ' '.join(Point.__fields__ + Color.__fields__) # combine fields - >>> Pixel = NamedTuple('Pixel', pixel_fields) + >>> Color = named_tuple('Color', 'red green blue') + >>> Pixel = named_tuple('Pixel', Point.__fields__ + Color.__fields__) >>> Pixel(11, 22, 128, 255, 0) Pixel(x=11, y=22, red=128, green=255, blue=0)' |