blob: ec7faeb17e07ed15f45be48d7f1b187321c7bfea [file] [log] [blame]
Brett Cannon23a4a7b2008-05-12 00:56:28 +00001__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
Raymond Hettinger2d32f632009-03-02 21:24:57 +00002 'UserString', 'Counter', 'OrderedDict']
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003# For bootstrapping reasons, the collection ABCs are defined in _abcoll.py.
4# They should however be considered an integral part of collections.py.
5from _abcoll import *
6import _abcoll
7__all__ += _abcoll.__all__
8
Christian Heimes99170a52007-12-19 02:07:34 +00009from _collections import deque, defaultdict
10from operator import itemgetter as _itemgetter
11from keyword import iskeyword as _iskeyword
12import sys as _sys
Raymond Hettingerb8baf632009-01-14 02:20:07 +000013import heapq as _heapq
Raymond Hettingerfa11db02010-09-12 04:12:42 +000014from weakref import proxy as _proxy
Raymond Hettingerea9f8db2009-03-02 21:28:41 +000015from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +000016from reprlib import recursive_repr as _recursive_repr
Raymond Hettinger2d32f632009-03-02 21:24:57 +000017
18################################################################################
19### OrderedDict
20################################################################################
21
Raymond Hettingerfa11db02010-09-12 04:12:42 +000022class _Link(object):
23 __slots__ = 'prev', 'next', 'key', '__weakref__'
24
Raymond Hettinger345c49b2011-01-01 23:51:55 +000025class OrderedDict(dict):
Raymond Hettinger18ed2cb2009-03-19 23:14:39 +000026 'Dictionary that remembers insertion order'
Raymond Hettingerf1736542009-03-23 05:19:21 +000027 # An inherited dict maps keys to values.
Raymond Hettinger18ed2cb2009-03-19 23:14:39 +000028 # The inherited dict provides __getitem__, __len__, __contains__, and get.
29 # The remaining methods are order-aware.
Raymond Hettinger5db3e012011-04-24 14:26:08 -070030 # Big-O running times for all methods are the same as regular dictionaries.
Raymond Hettingerf1736542009-03-23 05:19:21 +000031
Raymond Hettinger5db3e012011-04-24 14:26:08 -070032 # The internal self.__map dict maps keys to links in a doubly linked list.
Raymond Hettingerf1736542009-03-23 05:19:21 +000033 # The circular doubly linked list starts and ends with a sentinel element.
34 # The sentinel element never gets deleted (this simplifies the algorithm).
Raymond Hettinger5db3e012011-04-24 14:26:08 -070035 # The sentinel is in self.__hardroot with a weakref proxy in self.__root.
Raymond Hettingerc5c29c02010-09-12 18:13:46 +000036 # The prev/next links are weakref proxies (to prevent circular references).
37 # Individual links are kept alive by the hard reference in self.__map.
38 # Those hard references disappear when a key is deleted from an OrderedDict.
Raymond Hettinger2d32f632009-03-02 21:24:57 +000039
40 def __init__(self, *args, **kwds):
Raymond Hettinger5db3e012011-04-24 14:26:08 -070041 '''Initialize an ordered dictionary. The signature is the same as
42 regular dictionaries, but keyword arguments are not recommended because
43 their insertion order is arbitrary.
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000044
45 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +000046 if len(args) > 1:
47 raise TypeError('expected at most 1 arguments, got %d' % len(args))
Raymond Hettinger08c70cf2009-03-03 20:47:29 +000048 try:
Raymond Hettingerf1736542009-03-23 05:19:21 +000049 self.__root
Raymond Hettinger08c70cf2009-03-03 20:47:29 +000050 except AttributeError:
Raymond Hettingerf7328d02010-09-14 19:40:15 +000051 self.__hardroot = _Link()
52 self.__root = root = _proxy(self.__hardroot)
Raymond Hettingerfa11db02010-09-12 04:12:42 +000053 root.prev = root.next = root
Raymond Hettinger52dc06b2009-03-25 22:45:22 +000054 self.__map = {}
Raymond Hettinger32062e92011-01-01 22:38:00 +000055 self.__update(*args, **kwds)
Raymond Hettinger2d32f632009-03-02 21:24:57 +000056
Raymond Hettingerfa11db02010-09-12 04:12:42 +000057 def __setitem__(self, key, value,
58 dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000059 'od.__setitem__(i, y) <==> od[i]=y'
Raymond Hettinger5db3e012011-04-24 14:26:08 -070060 # Setting a new item creates a new link at the end of the linked list,
61 # and the inherited dictionary is updated with the new key/value pair.
Raymond Hettinger2d32f632009-03-02 21:24:57 +000062 if key not in self:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000063 self.__map[key] = link = Link()
Raymond Hettingerf1736542009-03-23 05:19:21 +000064 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000065 last = root.prev
66 link.prev, link.next, link.key = last, root, key
Raymond Hettingerf7328d02010-09-14 19:40:15 +000067 last.next = link
68 root.prev = proxy(link)
69 dict_setitem(self, key, value)
Raymond Hettinger2d32f632009-03-02 21:24:57 +000070
Raymond Hettingerfa11db02010-09-12 04:12:42 +000071 def __delitem__(self, key, dict_delitem=dict.__delitem__):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000072 'od.__delitem__(y) <==> del od[y]'
Raymond Hettinger5db3e012011-04-24 14:26:08 -070073 # Deleting an existing item uses self.__map to find the link which gets
74 # removed by updating the links in the predecessor and successor nodes.
Raymond Hettinger5be21b72010-08-01 22:10:57 +000075 dict_delitem(self, key)
Raymond Hettingerf1736542009-03-23 05:19:21 +000076 link = self.__map.pop(key)
Raymond Hettingerfa11db02010-09-12 04:12:42 +000077 link_prev = link.prev
78 link_next = link.next
79 link_prev.next = link_next
80 link_next.prev = link_prev
Raymond Hettinger2d32f632009-03-02 21:24:57 +000081
Raymond Hettingerfa11db02010-09-12 04:12:42 +000082 def __iter__(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000083 'od.__iter__() <==> iter(od)'
Raymond Hettingerf1736542009-03-23 05:19:21 +000084 # Traverse the linked list in order.
85 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000086 curr = root.next
Raymond Hettingerf1736542009-03-23 05:19:21 +000087 while curr is not root:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000088 yield curr.key
89 curr = curr.next
Raymond Hettinger2d32f632009-03-02 21:24:57 +000090
Raymond Hettingerfa11db02010-09-12 04:12:42 +000091 def __reversed__(self):
Raymond Hettinger2352cf32009-04-08 01:16:27 +000092 'od.__reversed__() <==> reversed(od)'
Raymond Hettingerf1736542009-03-23 05:19:21 +000093 # Traverse the linked list in reverse order.
94 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000095 curr = root.prev
Raymond Hettingerf1736542009-03-23 05:19:21 +000096 while curr is not root:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000097 yield curr.key
98 curr = curr.prev
Raymond Hettinger2d32f632009-03-02 21:24:57 +000099
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000100 def clear(self):
101 'od.clear() -> None. Remove all items from od.'
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000102 root = self.__root
103 root.prev = root.next = root
104 self.__map.clear()
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000105 dict.clear(self)
106
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000107 def popitem(self, last=True):
Raymond Hettinger331722d2010-09-02 18:44:16 +0000108 '''od.popitem() -> (k, v), return and remove a (key, value) pair.
109 Pairs are returned in LIFO order if last is true or FIFO order if false.
110
111 '''
112 if not self:
113 raise KeyError('dictionary is empty')
114 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000115 if last:
116 link = root.prev
117 link_prev = link.prev
118 link_prev.next = root
119 root.prev = link_prev
120 else:
121 link = root.next
122 link_next = link.next
123 root.next = link_next
124 link_next.prev = root
125 key = link.key
Raymond Hettinger331722d2010-09-02 18:44:16 +0000126 del self.__map[key]
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000127 value = dict.pop(self, key)
Raymond Hettinger331722d2010-09-02 18:44:16 +0000128 return key, value
129
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000130 def move_to_end(self, key, last=True):
131 '''Move an existing element to the end (or beginning if last==False).
132
133 Raises KeyError if the element does not exist.
134 When last=True, acts like a fast version of self[key]=self.pop(key).
135
136 '''
137 link = self.__map[key]
138 link_prev = link.prev
139 link_next = link.next
140 link_prev.next = link_next
141 link_next.prev = link_prev
142 root = self.__root
143 if last:
144 last = root.prev
145 link.prev = last
146 link.next = root
147 last.next = root.prev = link
148 else:
149 first = root.next
150 link.prev = root
151 link.next = first
152 root.next = first.prev = link
153
Raymond Hettinger35c87f22010-09-16 19:10:17 +0000154 def __sizeof__(self):
155 sizeof = _sys.getsizeof
156 n = len(self) + 1 # number of links including root
157 size = sizeof(self.__dict__) # instance dictionary
158 size += sizeof(self.__map) * 2 # internal dict and inherited dict
159 size += sizeof(self.__hardroot) * n # link objects
160 size += sizeof(self.__root) * n # proxy objects
161 return size
162
Raymond Hettinger32062e92011-01-01 22:38:00 +0000163 update = __update = MutableMapping.update
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000164 keys = MutableMapping.keys
165 values = MutableMapping.values
166 items = MutableMapping.items
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000167 __ne__ = MutableMapping.__ne__
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000168
Raymond Hettinger345c49b2011-01-01 23:51:55 +0000169 __marker = object()
170
171 def pop(self, key, default=__marker):
Raymond Hettinger5db3e012011-04-24 14:26:08 -0700172 '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
173 value. If key is not found, d is returned if given, otherwise KeyError
174 is raised.
175
176 '''
Raymond Hettinger345c49b2011-01-01 23:51:55 +0000177 if key in self:
178 result = self[key]
179 del self[key]
180 return result
181 if default is self.__marker:
182 raise KeyError(key)
183 return default
184
Raymond Hettingera673b1f2010-12-31 23:16:17 +0000185 def setdefault(self, key, default=None):
Raymond Hettinger5db3e012011-04-24 14:26:08 -0700186 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
Raymond Hettingera673b1f2010-12-31 23:16:17 +0000187 if key in self:
188 return self[key]
189 self[key] = default
190 return default
191
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000192 @_recursive_repr()
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000193 def __repr__(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000194 'od.__repr__() <==> repr(od)'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000195 if not self:
196 return '%s()' % (self.__class__.__name__,)
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000197 return '%s(%r)' % (self.__class__.__name__, list(self.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000198
Raymond Hettingerfc330ae2011-04-20 13:03:49 -0700199 def __reduce__(self):
200 'Return state information for pickling'
201 items = [[k, self[k]] for k in self]
202 inst_dict = vars(self).copy()
203 for k in vars(OrderedDict()):
204 inst_dict.pop(k, None)
205 if inst_dict:
206 return (self.__class__, (items,), inst_dict)
207 return self.__class__, (items,)
208
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000209 def copy(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000210 'od.copy() -> a shallow copy of od'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000211 return self.__class__(self)
212
213 @classmethod
214 def fromkeys(cls, iterable, value=None):
Raymond Hettinger5db3e012011-04-24 14:26:08 -0700215 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
216 If not specified, the value defaults to None.
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000217
218 '''
Raymond Hettinger5db3e012011-04-24 14:26:08 -0700219 self = cls()
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000220 for key in iterable:
Raymond Hettinger5db3e012011-04-24 14:26:08 -0700221 self[key] = value
222 return self
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000223
224 def __eq__(self, other):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000225 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
226 while comparison to a regular mapping is order-insensitive.
227
228 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000229 if isinstance(other, OrderedDict):
Raymond Hettinger798ee1a2009-03-23 18:29:11 +0000230 return len(self)==len(other) and \
231 all(p==q for p, q in zip(self.items(), other.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000232 return dict.__eq__(self, other)
233
Christian Heimes99170a52007-12-19 02:07:34 +0000234
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000235################################################################################
236### namedtuple
237################################################################################
238
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000239def namedtuple(typename, field_names, verbose=False, rename=False):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000240 """Returns a new subclass of tuple with named fields.
241
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000242 >>> Point = namedtuple('Point', 'x y')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000243 >>> Point.__doc__ # docstring for the new class
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 'Point(x, y)'
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000245 >>> p = Point(11, y=22) # instantiate with positional args or keywords
Christian Heimes99170a52007-12-19 02:07:34 +0000246 >>> p[0] + p[1] # indexable like a plain tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000247 33
Christian Heimes99170a52007-12-19 02:07:34 +0000248 >>> x, y = p # unpack like a regular tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000249 >>> x, y
250 (11, 22)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000251 >>> p.x + p.y # fields also accessable by name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000252 33
Christian Heimes0449f632007-12-15 01:27:15 +0000253 >>> d = p._asdict() # convert to a dictionary
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000254 >>> d['x']
255 11
256 >>> Point(**d) # convert from a dictionary
Guido van Rossumd8faa362007-04-27 19:54:29 +0000257 Point(x=11, y=22)
Christian Heimes0449f632007-12-15 01:27:15 +0000258 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000259 Point(x=100, y=22)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000260
261 """
262
Christian Heimes2380ac72008-01-09 00:17:24 +0000263 # Parse and validate the field names. Validation serves two purposes,
264 # generating informative error messages and preventing template injection attacks.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000265 if isinstance(field_names, str):
266 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000267 field_names = tuple(map(str, field_names))
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000268 if rename:
269 names = list(field_names)
270 seen = set()
271 for i, name in enumerate(names):
272 if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
273 or not name or name[0].isdigit() or name.startswith('_')
274 or name in seen):
Raymond Hettinger56145242009-04-02 22:31:59 +0000275 names[i] = '_%d' % i
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000276 seen.add(name)
277 field_names = tuple(names)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000278 for name in (typename,) + field_names:
Christian Heimesb9eccbf2007-12-05 20:18:38 +0000279 if not all(c.isalnum() or c=='_' for c in name):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000280 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
281 if _iskeyword(name):
282 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
283 if name[0].isdigit():
284 raise ValueError('Type names and field names cannot start with a number: %r' % name)
285 seen_names = set()
286 for name in field_names:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000287 if name.startswith('_') and not rename:
Christian Heimes0449f632007-12-15 01:27:15 +0000288 raise ValueError('Field names cannot start with an underscore: %r' % name)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000289 if name in seen_names:
290 raise ValueError('Encountered duplicate field name: %r' % name)
291 seen_names.add(name)
292
293 # Create and fill-in the class template
Christian Heimesfaf2f632008-01-06 16:59:19 +0000294 numfields = len(field_names)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000295 argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000296 reprtxt = ', '.join('%s=%%r' % name for name in field_names)
297 template = '''class %(typename)s(tuple):
Christian Heimes0449f632007-12-15 01:27:15 +0000298 '%(typename)s(%(argtxt)s)' \n
299 __slots__ = () \n
Christian Heimesfaf2f632008-01-06 16:59:19 +0000300 _fields = %(field_names)r \n
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000301 def __new__(_cls, %(argtxt)s):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000302 'Create new instance of %(typename)s(%(argtxt)s)'
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000303 return _tuple.__new__(_cls, (%(argtxt)s)) \n
Christian Heimesfaf2f632008-01-06 16:59:19 +0000304 @classmethod
Christian Heimes043d6f62008-01-07 17:19:16 +0000305 def _make(cls, iterable, new=tuple.__new__, len=len):
Christian Heimesfaf2f632008-01-06 16:59:19 +0000306 'Make a new %(typename)s object from a sequence or iterable'
Christian Heimes043d6f62008-01-07 17:19:16 +0000307 result = new(cls, iterable)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000308 if len(result) != %(numfields)d:
309 raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
310 return result \n
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000311 def __repr__(self):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000312 'Return a nicely formatted representation string'
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000313 return self.__class__.__name__ + '(%(reprtxt)s)' %% self \n
Raymond Hettingera4f52b12009-03-02 22:28:31 +0000314 def _asdict(self):
315 'Return a new OrderedDict which maps field names to their values'
316 return OrderedDict(zip(self._fields, self)) \n
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000317 def _replace(_self, **kwds):
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000318 'Return a new %(typename)s object replacing specified fields with new values'
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000319 result = _self._make(map(kwds.pop, %(field_names)r, _self))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000320 if kwds:
321 raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000322 return result \n
323 def __getnewargs__(self):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000324 'Return self as a plain tuple. Used by copy and pickle.'
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000325 return tuple(self) \n\n''' % locals()
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000326 for i, name in enumerate(field_names):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000327 template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000328 if verbose:
329 print(template)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000330
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000331 # Execute the template string in a temporary namespace and
332 # support tracing utilities by setting a value for frame.f_globals['__name__']
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000333 namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
334 OrderedDict=OrderedDict, _property=property, _tuple=tuple)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000335 try:
336 exec(template, namespace)
337 except SyntaxError as e:
Raymond Hettingerc1cc0d02010-09-16 08:06:05 +0000338 raise SyntaxError(e.msg + ':\n\n' + template)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000339 result = namespace[typename]
340
341 # For pickling to work, the __module__ variable needs to be set to the frame
342 # where the named tuple is created. Bypass this step in enviroments where
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000343 # sys._getframe is not defined (Jython for example) or sys._getframe is not
344 # defined for arguments greater than 0 (IronPython).
345 try:
Raymond Hettinger0f055172009-01-27 10:06:09 +0000346 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000347 except (AttributeError, ValueError):
348 pass
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000349
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000350 return result
Guido van Rossumd8faa362007-04-27 19:54:29 +0000351
Guido van Rossumd8faa362007-04-27 19:54:29 +0000352
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000353########################################################################
354### Counter
355########################################################################
356
Raymond Hettinger96f34102010-12-15 16:30:37 +0000357def _count_elements(mapping, iterable):
358 'Tally elements from the iterable.'
359 mapping_get = mapping.get
360 for elem in iterable:
361 mapping[elem] = mapping_get(elem, 0) + 1
362
363try: # Load C helper function if available
364 from _collections import _count_elements
365except ImportError:
366 pass
367
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000368class Counter(dict):
369 '''Dict subclass for counting hashable items. Sometimes called a bag
370 or multiset. Elements are stored as dictionary keys and their counts
371 are stored as dictionary values.
372
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000373 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000374
375 >>> c.most_common(3) # three most common elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000376 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000377 >>> sorted(c) # list all unique elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000378 ['a', 'b', 'c', 'd', 'e']
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000379 >>> ''.join(sorted(c.elements())) # list elements with repetitions
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000380 'aaaaabbbbcccdde'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000381 >>> sum(c.values()) # total of all counts
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000382 15
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000383
384 >>> c['a'] # count of letter 'a'
385 5
386 >>> for elem in 'shazam': # update counts from an iterable
387 ... c[elem] += 1 # by adding 1 to each element's count
388 >>> c['a'] # now there are seven 'a'
389 7
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000390 >>> del c['b'] # remove all 'b'
391 >>> c['b'] # now there are zero 'b'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000392 0
393
394 >>> d = Counter('simsalabim') # make another counter
395 >>> c.update(d) # add in the second counter
396 >>> c['a'] # now there are nine 'a'
397 9
398
399 >>> c.clear() # empty the counter
400 >>> c
401 Counter()
402
403 Note: If a count is set to zero or reduced to zero, it will remain
404 in the counter until the entry is deleted or the counter is cleared:
405
406 >>> c = Counter('aaabbc')
407 >>> c['b'] -= 2 # reduce the count of 'b' by two
408 >>> c.most_common() # 'b' is still in, but its count is zero
409 [('a', 3), ('c', 1), ('b', 0)]
410
411 '''
412 # References:
413 # http://en.wikipedia.org/wiki/Multiset
414 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
415 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
416 # http://code.activestate.com/recipes/259174/
417 # Knuth, TAOCP Vol. II section 4.6.3
418
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000419 def __init__(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000420 '''Create a new, empty Counter object. And if given, count elements
421 from an input iterable. Or, initialize the count from another mapping
422 of elements to their counts.
423
424 >>> c = Counter() # a new, empty counter
425 >>> c = Counter('gallahad') # a new counter from an iterable
426 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000427 >>> c = Counter(a=4, b=2) # a new counter from keyword args
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000428
429 '''
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000430 super().__init__()
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000431 self.update(iterable, **kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000432
433 def __missing__(self, key):
434 'The count of elements not in the Counter is zero.'
435 # Needed so that self[missing_item] does not raise KeyError
436 return 0
437
438 def most_common(self, n=None):
439 '''List the n most common elements and their counts from the most
440 common to the least. If n is None, then list all element counts.
441
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000442 >>> Counter('abcdeabcdabcaba').most_common(3)
443 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000444
445 '''
446 # Emulate Bag.sortedByCount from Smalltalk
447 if n is None:
448 return sorted(self.items(), key=_itemgetter(1), reverse=True)
449 return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
450
451 def elements(self):
452 '''Iterator over elements repeating each as many times as its count.
453
454 >>> c = Counter('ABCABC')
455 >>> sorted(c.elements())
456 ['A', 'A', 'B', 'B', 'C', 'C']
457
458 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
459 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
460 >>> product = 1
461 >>> for factor in prime_factors.elements(): # loop over factors
462 ... product *= factor # and multiply them
463 >>> product
464 1836
465
466 Note, if an element's count has been set to zero or is a negative
467 number, elements() will ignore it.
468
469 '''
470 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
471 return _chain.from_iterable(_starmap(_repeat, self.items()))
472
473 # Override dict methods where necessary
474
475 @classmethod
476 def fromkeys(cls, iterable, v=None):
477 # There is no equivalent method for counters because setting v=1
478 # means that no element can have a count greater than one.
479 raise NotImplementedError(
480 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
481
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000482 def update(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000483 '''Like dict.update() but add counts instead of replacing them.
484
485 Source can be an iterable, a dictionary, or another Counter instance.
486
487 >>> c = Counter('which')
488 >>> c.update('witch') # add elements from another iterable
489 >>> d = Counter('watch')
490 >>> c.update(d) # add elements from another counter
491 >>> c['h'] # four 'h' in which, witch, and watch
492 4
493
494 '''
495 # The regular dict.update() operation makes no sense here because the
496 # replace behavior results in the some of original untouched counts
497 # being mixed-in with all of the other counts for a mismash that
498 # doesn't have a straight-forward interpretation in most counting
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000499 # contexts. Instead, we implement straight-addition. Both the inputs
500 # and outputs are allowed to contain zero and negative counts.
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000501
502 if iterable is not None:
503 if isinstance(iterable, Mapping):
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000504 if self:
Raymond Hettingerf9092022009-06-29 18:30:43 +0000505 self_get = self.get
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000506 for elem, count in iterable.items():
Raymond Hettingerf9092022009-06-29 18:30:43 +0000507 self[elem] = count + self_get(elem, 0)
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000508 else:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000509 super().update(iterable) # fast path when counter is empty
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000510 else:
Raymond Hettinger96f34102010-12-15 16:30:37 +0000511 _count_elements(self, iterable)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000512 if kwds:
513 self.update(kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000514
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000515 def subtract(self, iterable=None, **kwds):
516 '''Like dict.update() but subtracts counts instead of replacing them.
517 Counts can be reduced below zero. Both the inputs and outputs are
518 allowed to contain zero and negative counts.
519
520 Source can be an iterable, a dictionary, or another Counter instance.
521
522 >>> c = Counter('which')
523 >>> c.subtract('witch') # subtract elements from another iterable
524 >>> c.subtract(Counter('watch')) # subtract elements from another counter
525 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
526 0
527 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
528 -1
529
530 '''
531 if iterable is not None:
Raymond Hettingerfc3c9cd2010-04-11 20:41:56 +0000532 self_get = self.get
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000533 if isinstance(iterable, Mapping):
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000534 for elem, count in iterable.items():
535 self[elem] = self_get(elem, 0) - count
536 else:
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000537 for elem in iterable:
538 self[elem] = self_get(elem, 0) - 1
539 if kwds:
540 self.subtract(kwds)
541
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000542 def copy(self):
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700543 'Return a shallow copy.'
544 return self.__class__(self)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000545
Raymond Hettingerff728162011-01-03 02:44:14 +0000546 def __reduce__(self):
547 return self.__class__, (dict(self),)
548
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000549 def __delitem__(self, elem):
550 'Like dict.__delitem__() but does not raise KeyError for missing values.'
551 if elem in self:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000552 super().__delitem__(elem)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000553
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000554 def __repr__(self):
555 if not self:
556 return '%s()' % self.__class__.__name__
557 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
558 return '%s({%s})' % (self.__class__.__name__, items)
559
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000560 # Multiset-style mathematical operations discussed in:
561 # Knuth TAOCP Volume II section 4.6.3 exercise 19
562 # and at http://en.wikipedia.org/wiki/Multiset
563 #
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000564 # Outputs guaranteed to only include positive counts.
565 #
566 # To strip negative and zero counts, add-in an empty counter:
567 # c += Counter()
568
569 def __add__(self, other):
570 '''Add counts from two counters.
571
572 >>> Counter('abbb') + Counter('bcc')
573 Counter({'b': 4, 'c': 2, 'a': 1})
574
575 '''
576 if not isinstance(other, Counter):
577 return NotImplemented
578 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700579 for elem, count in self.items():
580 newcount = count + other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000581 if newcount > 0:
582 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700583 for elem, count in other.items():
584 if elem not in self and count > 0:
585 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000586 return result
587
588 def __sub__(self, other):
589 ''' Subtract count, but keep only results with positive counts.
590
591 >>> Counter('abbbc') - Counter('bccd')
592 Counter({'b': 2, 'a': 1})
593
594 '''
595 if not isinstance(other, Counter):
596 return NotImplemented
597 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700598 for elem, count in self.items():
599 newcount = count - other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000600 if newcount > 0:
601 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700602 for elem, count in other.items():
603 if elem not in self and count < 0:
604 result[elem] = 0 - count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000605 return result
606
607 def __or__(self, other):
608 '''Union is the maximum of value in either of the input counters.
609
610 >>> Counter('abbb') | Counter('bcc')
611 Counter({'b': 3, 'c': 2, 'a': 1})
612
613 '''
614 if not isinstance(other, Counter):
615 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000616 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700617 for elem, count in self.items():
618 other_count = other[elem]
619 newcount = other_count if count < other_count else count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000620 if newcount > 0:
621 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700622 for elem, count in other.items():
623 if elem not in self and count > 0:
624 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000625 return result
626
627 def __and__(self, other):
628 ''' Intersection is the minimum of corresponding counts.
629
630 >>> Counter('abbb') & Counter('bcc')
631 Counter({'b': 1})
632
633 '''
634 if not isinstance(other, Counter):
635 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000636 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700637 for elem, count in self.items():
638 other_count = other[elem]
639 newcount = count if count < other_count else other_count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000640 if newcount > 0:
641 result[elem] = newcount
642 return result
643
Guido van Rossumd8faa362007-04-27 19:54:29 +0000644
Raymond Hettingere6603602011-02-21 19:38:53 +0000645########################################################################
646### ChainMap (helper for configparser)
647########################################################################
648
649class _ChainMap(MutableMapping):
650 ''' A ChainMap groups multiple dicts (or other mappings) together
651 to create a single, updateable view.
652
653 The underlying mappings are stored in a list. That list is public and can
654 accessed or updated using the *maps* attribute. There is no other state.
655
656 Lookups search the underlying mappings successively until a key is found.
657 In contrast, writes, updates, and deletions only operate on the first
658 mapping.
659
660 '''
661
662 def __init__(self, *maps):
663 '''Initialize a ChainMap by setting *maps* to the given mappings.
664 If no mappings are provided, a single empty dictionary is used.
665
666 '''
667 self.maps = list(maps) or [{}] # always at least one map
668
669 def __missing__(self, key):
670 raise KeyError(key)
671
672 def __getitem__(self, key):
673 for mapping in self.maps:
674 try:
675 return mapping[key] # can't use 'key in mapping' with defaultdict
676 except KeyError:
677 pass
678 return self.__missing__(key) # support subclasses that define __missing__
679
680 def get(self, key, default=None):
681 return self[key] if key in self else default
682
683 def __len__(self):
684 return len(set().union(*self.maps)) # reuses stored hash values if possible
685
686 def __iter__(self):
687 return iter(set().union(*self.maps))
688
689 def __contains__(self, key):
690 return any(key in m for m in self.maps)
691
692 @_recursive_repr()
693 def __repr__(self):
694 return '{0.__class__.__name__}({1})'.format(
695 self, ', '.join(map(repr, self.maps)))
696
697 @classmethod
698 def fromkeys(cls, iterable, *args):
699 'Create a ChainMap with a single dict created from the iterable.'
700 return cls(dict.fromkeys(iterable, *args))
701
702 def copy(self):
703 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
704 return self.__class__(self.maps[0].copy(), *self.maps[1:])
705
706 __copy__ = copy
707
Raymond Hettingerdcb29c92011-02-23 08:28:06 +0000708 def new_child(self): # like Django's Context.push()
709 'New ChainMap with a new dict followed by all previous maps.'
710 return self.__class__({}, *self.maps)
711
712 @property
713 def parents(self): # like Django's Context.pop()
714 'New ChainMap from maps[1:].'
715 return self.__class__(*self.maps[1:])
716
Raymond Hettingere6603602011-02-21 19:38:53 +0000717 def __setitem__(self, key, value):
718 self.maps[0][key] = value
719
720 def __delitem__(self, key):
721 try:
722 del self.maps[0][key]
723 except KeyError:
724 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
725
726 def popitem(self):
727 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
728 try:
729 return self.maps[0].popitem()
730 except KeyError:
731 raise KeyError('No keys found in the first mapping.')
732
733 def pop(self, key, *args):
734 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
735 try:
736 return self.maps[0].pop(key, *args)
737 except KeyError:
738 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
739
740 def clear(self):
741 'Clear maps[0], leaving maps[1:] intact.'
742 self.maps[0].clear()
743
744
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000745################################################################################
746### UserDict
747################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +0000748
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000749class UserDict(MutableMapping):
750
751 # Start by filling-out the abstract methods
752 def __init__(self, dict=None, **kwargs):
753 self.data = {}
754 if dict is not None:
755 self.update(dict)
756 if len(kwargs):
757 self.update(kwargs)
758 def __len__(self): return len(self.data)
759 def __getitem__(self, key):
760 if key in self.data:
761 return self.data[key]
762 if hasattr(self.__class__, "__missing__"):
763 return self.__class__.__missing__(self, key)
764 raise KeyError(key)
765 def __setitem__(self, key, item): self.data[key] = item
766 def __delitem__(self, key): del self.data[key]
767 def __iter__(self):
768 return iter(self.data)
769
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000770 # Modify __contains__ to work correctly when __missing__ is present
771 def __contains__(self, key):
772 return key in self.data
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000773
774 # Now, add the methods in dicts but not in MutableMapping
775 def __repr__(self): return repr(self.data)
776 def copy(self):
777 if self.__class__ is UserDict:
778 return UserDict(self.data.copy())
779 import copy
780 data = self.data
781 try:
782 self.data = {}
783 c = copy.copy(self)
784 finally:
785 self.data = data
786 c.update(self)
787 return c
788 @classmethod
789 def fromkeys(cls, iterable, value=None):
790 d = cls()
791 for key in iterable:
792 d[key] = value
793 return d
794
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000795
796
797################################################################################
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000798### UserList
799################################################################################
800
801class UserList(MutableSequence):
802 """A more or less complete user-defined wrapper around list objects."""
803 def __init__(self, initlist=None):
804 self.data = []
805 if initlist is not None:
806 # XXX should this accept an arbitrary sequence?
807 if type(initlist) == type(self.data):
808 self.data[:] = initlist
809 elif isinstance(initlist, UserList):
810 self.data[:] = initlist.data[:]
811 else:
812 self.data = list(initlist)
813 def __repr__(self): return repr(self.data)
814 def __lt__(self, other): return self.data < self.__cast(other)
815 def __le__(self, other): return self.data <= self.__cast(other)
816 def __eq__(self, other): return self.data == self.__cast(other)
817 def __ne__(self, other): return self.data != self.__cast(other)
818 def __gt__(self, other): return self.data > self.__cast(other)
819 def __ge__(self, other): return self.data >= self.__cast(other)
820 def __cast(self, other):
821 return other.data if isinstance(other, UserList) else other
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000822 def __contains__(self, item): return item in self.data
823 def __len__(self): return len(self.data)
824 def __getitem__(self, i): return self.data[i]
825 def __setitem__(self, i, item): self.data[i] = item
826 def __delitem__(self, i): del self.data[i]
827 def __add__(self, other):
828 if isinstance(other, UserList):
829 return self.__class__(self.data + other.data)
830 elif isinstance(other, type(self.data)):
831 return self.__class__(self.data + other)
832 return self.__class__(self.data + list(other))
833 def __radd__(self, other):
834 if isinstance(other, UserList):
835 return self.__class__(other.data + self.data)
836 elif isinstance(other, type(self.data)):
837 return self.__class__(other + self.data)
838 return self.__class__(list(other) + self.data)
839 def __iadd__(self, other):
840 if isinstance(other, UserList):
841 self.data += other.data
842 elif isinstance(other, type(self.data)):
843 self.data += other
844 else:
845 self.data += list(other)
846 return self
847 def __mul__(self, n):
848 return self.__class__(self.data*n)
849 __rmul__ = __mul__
850 def __imul__(self, n):
851 self.data *= n
852 return self
853 def append(self, item): self.data.append(item)
854 def insert(self, i, item): self.data.insert(i, item)
855 def pop(self, i=-1): return self.data.pop(i)
856 def remove(self, item): self.data.remove(item)
857 def count(self, item): return self.data.count(item)
858 def index(self, item, *args): return self.data.index(item, *args)
859 def reverse(self): self.data.reverse()
860 def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
861 def extend(self, other):
862 if isinstance(other, UserList):
863 self.data.extend(other.data)
864 else:
865 self.data.extend(other)
866
867
868
869################################################################################
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000870### UserString
871################################################################################
872
873class UserString(Sequence):
874 def __init__(self, seq):
875 if isinstance(seq, str):
876 self.data = seq
877 elif isinstance(seq, UserString):
878 self.data = seq.data[:]
879 else:
880 self.data = str(seq)
881 def __str__(self): return str(self.data)
882 def __repr__(self): return repr(self.data)
883 def __int__(self): return int(self.data)
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000884 def __float__(self): return float(self.data)
885 def __complex__(self): return complex(self.data)
886 def __hash__(self): return hash(self.data)
887
888 def __eq__(self, string):
889 if isinstance(string, UserString):
890 return self.data == string.data
891 return self.data == string
892 def __ne__(self, string):
893 if isinstance(string, UserString):
894 return self.data != string.data
895 return self.data != string
896 def __lt__(self, string):
897 if isinstance(string, UserString):
898 return self.data < string.data
899 return self.data < string
900 def __le__(self, string):
901 if isinstance(string, UserString):
902 return self.data <= string.data
903 return self.data <= string
904 def __gt__(self, string):
905 if isinstance(string, UserString):
906 return self.data > string.data
907 return self.data > string
908 def __ge__(self, string):
909 if isinstance(string, UserString):
910 return self.data >= string.data
911 return self.data >= string
912
913 def __contains__(self, char):
914 if isinstance(char, UserString):
915 char = char.data
916 return char in self.data
917
918 def __len__(self): return len(self.data)
919 def __getitem__(self, index): return self.__class__(self.data[index])
920 def __add__(self, other):
921 if isinstance(other, UserString):
922 return self.__class__(self.data + other.data)
923 elif isinstance(other, str):
924 return self.__class__(self.data + other)
925 return self.__class__(self.data + str(other))
926 def __radd__(self, other):
927 if isinstance(other, str):
928 return self.__class__(other + self.data)
929 return self.__class__(str(other) + self.data)
930 def __mul__(self, n):
931 return self.__class__(self.data*n)
932 __rmul__ = __mul__
933 def __mod__(self, args):
934 return self.__class__(self.data % args)
935
936 # the following methods are defined in alphabetical order:
937 def capitalize(self): return self.__class__(self.data.capitalize())
938 def center(self, width, *args):
939 return self.__class__(self.data.center(width, *args))
940 def count(self, sub, start=0, end=_sys.maxsize):
941 if isinstance(sub, UserString):
942 sub = sub.data
943 return self.data.count(sub, start, end)
944 def encode(self, encoding=None, errors=None): # XXX improve this?
945 if encoding:
946 if errors:
947 return self.__class__(self.data.encode(encoding, errors))
948 return self.__class__(self.data.encode(encoding))
949 return self.__class__(self.data.encode())
950 def endswith(self, suffix, start=0, end=_sys.maxsize):
951 return self.data.endswith(suffix, start, end)
952 def expandtabs(self, tabsize=8):
953 return self.__class__(self.data.expandtabs(tabsize))
954 def find(self, sub, start=0, end=_sys.maxsize):
955 if isinstance(sub, UserString):
956 sub = sub.data
957 return self.data.find(sub, start, end)
958 def format(self, *args, **kwds):
959 return self.data.format(*args, **kwds)
960 def index(self, sub, start=0, end=_sys.maxsize):
961 return self.data.index(sub, start, end)
962 def isalpha(self): return self.data.isalpha()
963 def isalnum(self): return self.data.isalnum()
964 def isdecimal(self): return self.data.isdecimal()
965 def isdigit(self): return self.data.isdigit()
966 def isidentifier(self): return self.data.isidentifier()
967 def islower(self): return self.data.islower()
968 def isnumeric(self): return self.data.isnumeric()
969 def isspace(self): return self.data.isspace()
970 def istitle(self): return self.data.istitle()
971 def isupper(self): return self.data.isupper()
972 def join(self, seq): return self.data.join(seq)
973 def ljust(self, width, *args):
974 return self.__class__(self.data.ljust(width, *args))
975 def lower(self): return self.__class__(self.data.lower())
976 def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
977 def partition(self, sep):
978 return self.data.partition(sep)
979 def replace(self, old, new, maxsplit=-1):
980 if isinstance(old, UserString):
981 old = old.data
982 if isinstance(new, UserString):
983 new = new.data
984 return self.__class__(self.data.replace(old, new, maxsplit))
985 def rfind(self, sub, start=0, end=_sys.maxsize):
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +0000986 if isinstance(sub, UserString):
987 sub = sub.data
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000988 return self.data.rfind(sub, start, end)
989 def rindex(self, sub, start=0, end=_sys.maxsize):
990 return self.data.rindex(sub, start, end)
991 def rjust(self, width, *args):
992 return self.__class__(self.data.rjust(width, *args))
993 def rpartition(self, sep):
994 return self.data.rpartition(sep)
995 def rstrip(self, chars=None):
996 return self.__class__(self.data.rstrip(chars))
997 def split(self, sep=None, maxsplit=-1):
998 return self.data.split(sep, maxsplit)
999 def rsplit(self, sep=None, maxsplit=-1):
1000 return self.data.rsplit(sep, maxsplit)
1001 def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1002 def startswith(self, prefix, start=0, end=_sys.maxsize):
1003 return self.data.startswith(prefix, start, end)
1004 def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1005 def swapcase(self): return self.__class__(self.data.swapcase())
1006 def title(self): return self.__class__(self.data.title())
1007 def translate(self, *args):
1008 return self.__class__(self.data.translate(*args))
1009 def upper(self): return self.__class__(self.data.upper())
1010 def zfill(self, width): return self.__class__(self.data.zfill(width))
1011
1012
1013
1014################################################################################
Raymond Hettinger48b8b662008-02-05 01:53:00 +00001015### Simple tests
1016################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +00001017
1018if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001019 # verify that instances can be pickled
Guido van Rossum99603b02007-07-20 00:22:32 +00001020 from pickle import loads, dumps
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001021 Point = namedtuple('Point', 'x, y', True)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001022 p = Point(x=10, y=20)
1023 assert p == loads(dumps(p))
1024
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001025 # test and demonstrate ability to override methods
Christian Heimes043d6f62008-01-07 17:19:16 +00001026 class Point(namedtuple('Point', 'x y')):
Christian Heimes25bb7832008-01-11 16:17:00 +00001027 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001028 @property
1029 def hypot(self):
1030 return (self.x ** 2 + self.y ** 2) ** 0.5
Christian Heimes790c8232008-01-07 21:14:23 +00001031 def __str__(self):
Christian Heimes25bb7832008-01-11 16:17:00 +00001032 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
Christian Heimes043d6f62008-01-07 17:19:16 +00001033
Christian Heimes25bb7832008-01-11 16:17:00 +00001034 for p in Point(3, 4), Point(14, 5/7.):
Christian Heimes790c8232008-01-07 21:14:23 +00001035 print (p)
Christian Heimes043d6f62008-01-07 17:19:16 +00001036
1037 class Point(namedtuple('Point', 'x y')):
1038 'Point class with optimized _make() and _replace() without error-checking'
Christian Heimes25bb7832008-01-11 16:17:00 +00001039 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001040 _make = classmethod(tuple.__new__)
1041 def _replace(self, _map=map, **kwds):
Christian Heimes2380ac72008-01-09 00:17:24 +00001042 return self._make(_map(kwds.get, ('x', 'y'), self))
Christian Heimes043d6f62008-01-07 17:19:16 +00001043
1044 print(Point(11, 22)._replace(x=100))
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001045
Christian Heimes25bb7832008-01-11 16:17:00 +00001046 Point3D = namedtuple('Point3D', Point._fields + ('z',))
1047 print(Point3D.__doc__)
1048
Guido van Rossumd8faa362007-04-27 19:54:29 +00001049 import doctest
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001050 TestResults = namedtuple('TestResults', 'failed attempted')
Guido van Rossumd8faa362007-04-27 19:54:29 +00001051 print(TestResults(*doctest.testmod()))