blob: 84cc507cb8de2343907fc482151bf74e90b387b8 [file] [log] [blame]
Raymond Hettingere52f3b12004-01-29 07:27:45 +00001\section{\module{collections} ---
Raymond Hettinger5c5eb862004-02-07 21:13:00 +00002 High-performance container datatypes}
Raymond Hettingere52f3b12004-01-29 07:27:45 +00003
4\declaremodule{standard}{collections}
5\modulesynopsis{High-performance datatypes}
6\moduleauthor{Raymond Hettinger}{python@rcn.com}
7\sectionauthor{Raymond Hettinger}{python@rcn.com}
8\versionadded{2.4}
9
10
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000011This module implements high-performance container datatypes. Currently, the
Raymond Hettingere52f3b12004-01-29 07:27:45 +000012only datatype is a deque. Future additions may include B-trees
13and Fibonacci heaps.
14
15\begin{funcdesc}{deque}{\optional{iterable}}
16 Returns a new deque objected initialized left-to-right (using
17 \method{append()}) with data from \var{iterable}. If \var{iterable}
18 is not specified, the new deque is empty.
19
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000020 Deques are a generalization of stacks and queues (the name is pronounced
21 ``deck'' and is short for ``double-ended queue''). Deques support
22 thread-safe, memory efficient appends and pops from either side of the deque
23 with approximately the same \code{O(1)} performance in either direction.
24
25 Though \class{list} objects support similar operations, they are optimized
26 for fast fixed-length operations and incur \code{O(n)} memory movement costs
27 for \samp{pop(0)} and \samp{insert(0, v)} operations which change both the
28 size and position of the underlying data representation.
Raymond Hettingere52f3b12004-01-29 07:27:45 +000029 \versionadded{2.4}
30\end{funcdesc}
31
32Deque objects support the following methods:
33
34\begin{methoddesc}{append}{x}
35 Add \var{x} to the right side of the deque.
36\end{methoddesc}
37
38\begin{methoddesc}{appendleft}{x}
39 Add \var{x} to the left side of the deque.
40\end{methoddesc}
41
42\begin{methoddesc}{clear}{}
43 Remove all elements from the deque leaving it with length 0.
44\end{methoddesc}
45
Raymond Hettinger3ba85c22004-02-06 19:04:56 +000046\begin{methoddesc}{extend}{iterable}
47 Extend the right side of the deque by appending elements from
48 the iterable argument.
49\end{methoddesc}
50
51\begin{methoddesc}{extendleft}{iterable}
52 Extend the left side of the deque by appending elements from
53 \var{iterable}. Note, the series of left appends results in
54 reversing the order of elements in the iterable argument.
55\end{methoddesc}
56
Raymond Hettingere52f3b12004-01-29 07:27:45 +000057\begin{methoddesc}{pop}{}
58 Remove and return an element from the right side of the deque.
Raymond Hettinger738ec902004-02-29 02:15:56 +000059 If no elements are present, raises a \exception{IndexError}.
Raymond Hettingere52f3b12004-01-29 07:27:45 +000060\end{methoddesc}
61
62\begin{methoddesc}{popleft}{}
63 Remove and return an element from the left side of the deque.
Raymond Hettinger738ec902004-02-29 02:15:56 +000064 If no elements are present, raises a \exception{IndexError}.
65\end{methoddesc}
66
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000067\begin{methoddesc}{rotate}{n}
68 Rotate the deque \var{n} steps to the right. If \var{n} is
69 negative, rotate to the left. Rotating one step to the right
Raymond Hettingerf5f9a3702004-04-30 22:52:50 +000070 is equivalent to: \samp{d.appendleft(d.pop())}.
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000071\end{methoddesc}
72
73In addition to the above, deques support iteration, pickling, \samp{len(d)},
Raymond Hettinger0a4977c2004-03-01 23:16:22 +000074\samp{reversed(d)}, \samp{copy.copy(d)}, \samp{copy.deepcopy(d)},
75membership testing with the \keyword{in} operator, and subscript references
76such as \samp{d[-1]}.
Raymond Hettingere52f3b12004-01-29 07:27:45 +000077
78Example:
79
80\begin{verbatim}
81>>> from collections import deque
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000082>>> d = deque('ghi') # make a new deque with three items
83>>> for elem in d: # iterate over the deque's elements
Raymond Hettinger738ec902004-02-29 02:15:56 +000084... print elem.upper()
Raymond Hettingere52f3b12004-01-29 07:27:45 +000085G
86H
87I
Raymond Hettinger738ec902004-02-29 02:15:56 +000088
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000089>>> d.append('j') # add a new entry to the right side
90>>> d.appendleft('f') # add a new entry to the left side
91>>> d # show the representation of the deque
Raymond Hettingere52f3b12004-01-29 07:27:45 +000092deque(['f', 'g', 'h', 'i', 'j'])
Raymond Hettinger738ec902004-02-29 02:15:56 +000093
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000094>>> d.pop() # return and remove the rightmost item
Raymond Hettingere52f3b12004-01-29 07:27:45 +000095'j'
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000096>>> d.popleft() # return and remove the leftmost item
Raymond Hettingere52f3b12004-01-29 07:27:45 +000097'f'
Raymond Hettinger5c5eb862004-02-07 21:13:00 +000098>>> list(d) # list the contents of the deque
Raymond Hettingere52f3b12004-01-29 07:27:45 +000099['g', 'h', 'i']
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000100>>> d[0] # peek at leftmost item
Raymond Hettinger738ec902004-02-29 02:15:56 +0000101'g'
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000102>>> d[-1] # peek at rightmost item
Raymond Hettinger738ec902004-02-29 02:15:56 +0000103'i'
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000104
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000105>>> list(reversed(d)) # list the contents of a deque in reverse
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000106['i', 'h', 'g']
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000107>>> 'h' in d # search the deque
Raymond Hettingere52f3b12004-01-29 07:27:45 +0000108True
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000109>>> d.extend('jkl') # add multiple elements at once
Raymond Hettingere52f3b12004-01-29 07:27:45 +0000110>>> d
111deque(['g', 'h', 'i', 'j', 'k', 'l'])
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000112>>> d.rotate(1) # right rotation
113>>> d
114deque(['l', 'g', 'h', 'i', 'j', 'k'])
115>>> d.rotate(-1) # left rotation
116>>> d
117deque(['g', 'h', 'i', 'j', 'k', 'l'])
Raymond Hettinger738ec902004-02-29 02:15:56 +0000118
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000119>>> deque(reversed(d)) # make a new deque in reverse order
120deque(['l', 'k', 'j', 'i', 'h', 'g'])
121>>> d.clear() # empty the deque
122>>> d.pop() # cannot pop from an empty deque
Raymond Hettingere52f3b12004-01-29 07:27:45 +0000123Traceback (most recent call last):
124 File "<pyshell#6>", line 1, in -toplevel-
125 d.pop()
Raymond Hettinger738ec902004-02-29 02:15:56 +0000126IndexError: pop from an empty deque
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000127
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000128>>> d.extendleft('abc') # extendleft() reverses the input order
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000129>>> d
130deque(['c', 'b', 'a'])
Raymond Hettingerf5f9a3702004-04-30 22:52:50 +0000131\end{verbatim}
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000132
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000133\subsection{Recipes \label{deque-recipes}}
134
135This section shows various approaches to working with deques.
136
137The \method{rotate()} method provides a way to implement \class{deque}
Raymond Hettinger2e669402004-06-12 07:59:40 +0000138slicing and deletion. For example, a pure python implementation of
139\code{del d[n]} relies on the \method{rotate()} method to position
140elements to be popped:
141
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000142\begin{verbatim}
143def delete_nth(d, n):
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000144 d.rotate(-n)
145 d.popleft()
146 d.rotate(n)
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000147\end{verbatim}
148
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000149To implement \class{deque} slicing, use a similar approach applying
150\method{rotate()} to bring a target element to the left side of the deque.
151Remove old entries with \method{popleft()}, add new entries with
152\method{extend()}, and then reverse the rotation.
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000153
154With minor variations on that approach, it is easy to implement Forth style
155stack manipulations such as \code{dup}, \code{drop}, \code{swap}, \code{over},
156\code{pick}, \code{rot}, and \code{roll}.
Raymond Hettingerf5f9a3702004-04-30 22:52:50 +0000157
158A roundrobin task server can be built from a \class{deque} using
159\method{popleft()} to select the current task and \method{append()}
160to add it back to the tasklist if the input stream is not exhausted:
161
162\begin{verbatim}
163def roundrobin(*iterables):
164 pending = deque(iter(i) for i in iterables)
165 while pending:
166 task = pending.popleft()
167 try:
168 yield task.next()
169 except StopIteration:
170 continue
171 pending.append(task)
172
173>>> for value in roundrobin('abc', 'd', 'efgh'):
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000174... print value
Raymond Hettingerf5f9a3702004-04-30 22:52:50 +0000175
176a
177d
178e
179b
180f
181c
182g
183h
184
185\end{verbatim}
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000186
187
188Multi-pass data reduction algorithms can be succinctly expressed and
Raymond Hettinger2e669402004-06-12 07:59:40 +0000189efficiently coded by extracting elements with multiple calls to
190\method{popleft()}, applying the reduction function, and calling
191\method{append()} to add the result back to the queue.
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000192
193For example, building a balanced binary tree of nested lists entails
194reducing two adjacent nodes into one by grouping them in a list:
195
196\begin{verbatim}
197def maketree(iterable):
198 d = deque(iterable)
199 while len(d) > 1:
200 pair = [d.popleft(), d.popleft()]
201 d.append(pair)
202 return list(d)
203
204>>> print maketree('abcdefgh')
205[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
206
207\end{verbatim}