blob: 33aedd973a50edb3616018a3fda6a1d89acc6c7c [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 Hettingereaac4f02012-01-26 00:14:16 -080036 # The prev links are weakref proxies (to prevent circular references).
Raymond Hettingerc5c29c02010-09-12 18:13:46 +000037 # 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
Raymond Hettinger81b96562011-05-02 09:50:15 -0700239_class_template = '''\
240from builtins import property as _property, tuple as _tuple
241from operator import itemgetter as _itemgetter
242from collections import OrderedDict
243
244class {typename}(tuple):
245 '{typename}({arg_list})'
246
247 __slots__ = ()
248
249 _fields = {field_names!r}
250
251 def __new__(_cls, {arg_list}):
252 'Create new instance of {typename}({arg_list})'
253 return _tuple.__new__(_cls, ({arg_list}))
254
255 @classmethod
256 def _make(cls, iterable, new=tuple.__new__, len=len):
257 'Make a new {typename} object from a sequence or iterable'
258 result = new(cls, iterable)
259 if len(result) != {num_fields:d}:
260 raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result))
261 return result
262
263 def __repr__(self):
264 'Return a nicely formatted representation string'
265 return self.__class__.__name__ + '({repr_fmt})' % self
266
267 def _asdict(self):
268 'Return a new OrderedDict which maps field names to their values'
269 return OrderedDict(zip(self._fields, self))
270
Raymond Hettinger3d890572011-06-02 23:40:24 -0700271 __dict__ = property(_asdict)
272
Raymond Hettinger81b96562011-05-02 09:50:15 -0700273 def _replace(_self, **kwds):
274 'Return a new {typename} object replacing specified fields with new values'
275 result = _self._make(map(kwds.pop, {field_names!r}, _self))
276 if kwds:
277 raise ValueError('Got unexpected field names: %r' % list(kwds))
278 return result
279
280 def __getnewargs__(self):
281 'Return self as a plain tuple. Used by copy and pickle.'
282 return tuple(self)
283
Georg Brandlce654f42013-05-12 11:09:11 +0200284 def __getstate__(self):
285 'Exclude the OrderedDict from pickling'
286 return None
287
Raymond Hettinger81b96562011-05-02 09:50:15 -0700288{field_defs}
289'''
290
291_repr_template = '{name}=%r'
292
293_field_template = '''\
294 {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
295'''
296
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000297def namedtuple(typename, field_names, verbose=False, rename=False):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000298 """Returns a new subclass of tuple with named fields.
299
Raymond Hettinger81b96562011-05-02 09:50:15 -0700300 >>> Point = namedtuple('Point', ['x', 'y'])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000301 >>> Point.__doc__ # docstring for the new class
Guido van Rossumd8faa362007-04-27 19:54:29 +0000302 'Point(x, y)'
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000303 >>> p = Point(11, y=22) # instantiate with positional args or keywords
Christian Heimes99170a52007-12-19 02:07:34 +0000304 >>> p[0] + p[1] # indexable like a plain tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000305 33
Christian Heimes99170a52007-12-19 02:07:34 +0000306 >>> x, y = p # unpack like a regular tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000307 >>> x, y
308 (11, 22)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000309 >>> p.x + p.y # fields also accessable by name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000310 33
Christian Heimes0449f632007-12-15 01:27:15 +0000311 >>> d = p._asdict() # convert to a dictionary
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000312 >>> d['x']
313 11
314 >>> Point(**d) # convert from a dictionary
Guido van Rossumd8faa362007-04-27 19:54:29 +0000315 Point(x=11, y=22)
Christian Heimes0449f632007-12-15 01:27:15 +0000316 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000317 Point(x=100, y=22)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000318
319 """
320
Christian Heimes2380ac72008-01-09 00:17:24 +0000321 # Parse and validate the field names. Validation serves two purposes,
322 # generating informative error messages and preventing template injection attacks.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000323 if isinstance(field_names, str):
324 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
Raymond Hettinger81b96562011-05-02 09:50:15 -0700325 field_names = list(map(str, field_names))
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000326 if rename:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000327 seen = set()
Raymond Hettinger81b96562011-05-02 09:50:15 -0700328 for index, name in enumerate(field_names):
329 if (not all(c.isalnum() or c=='_' for c in name)
330 or _iskeyword(name)
331 or not name
332 or name[0].isdigit()
333 or name.startswith('_')
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000334 or name in seen):
Raymond Hettinger81b96562011-05-02 09:50:15 -0700335 field_names[index] = '_%d' % index
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000336 seen.add(name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700337 for name in [typename] + field_names:
Christian Heimesb9eccbf2007-12-05 20:18:38 +0000338 if not all(c.isalnum() or c=='_' for c in name):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000339 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
340 if _iskeyword(name):
341 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
342 if name[0].isdigit():
343 raise ValueError('Type names and field names cannot start with a number: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700344 seen = set()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000345 for name in field_names:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000346 if name.startswith('_') and not rename:
Christian Heimes0449f632007-12-15 01:27:15 +0000347 raise ValueError('Field names cannot start with an underscore: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700348 if name in seen:
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000349 raise ValueError('Encountered duplicate field name: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700350 seen.add(name)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000351
Raymond Hettinger81b96562011-05-02 09:50:15 -0700352 # Fill-in the class template
353 class_definition = _class_template.format(
354 typename = typename,
355 field_names = tuple(field_names),
356 num_fields = len(field_names),
357 arg_list = repr(tuple(field_names)).replace("'", "")[1:-1],
358 repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names),
359 field_defs = '\n'.join(_field_template.format(index=index, name=name)
360 for index, name in enumerate(field_names))
361 )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000362
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000363 # Execute the template string in a temporary namespace and
364 # support tracing utilities by setting a value for frame.f_globals['__name__']
Raymond Hettinger81b96562011-05-02 09:50:15 -0700365 namespace = dict(__name__='namedtuple_%s' % typename)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000366 try:
Raymond Hettinger81b96562011-05-02 09:50:15 -0700367 exec(class_definition, namespace)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000368 except SyntaxError as e:
Raymond Hettinger81b96562011-05-02 09:50:15 -0700369 raise SyntaxError(e.msg + ':\n\n' + class_definition)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000370 result = namespace[typename]
Raymond Hettinger81b96562011-05-02 09:50:15 -0700371 if verbose:
372 print(class_definition)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000373
374 # For pickling to work, the __module__ variable needs to be set to the frame
375 # where the named tuple is created. Bypass this step in enviroments where
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000376 # sys._getframe is not defined (Jython for example) or sys._getframe is not
377 # defined for arguments greater than 0 (IronPython).
378 try:
Raymond Hettinger0f055172009-01-27 10:06:09 +0000379 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000380 except (AttributeError, ValueError):
381 pass
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000382
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000383 return result
Guido van Rossumd8faa362007-04-27 19:54:29 +0000384
Guido van Rossumd8faa362007-04-27 19:54:29 +0000385
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000386########################################################################
387### Counter
388########################################################################
389
Raymond Hettinger96f34102010-12-15 16:30:37 +0000390def _count_elements(mapping, iterable):
391 'Tally elements from the iterable.'
392 mapping_get = mapping.get
393 for elem in iterable:
394 mapping[elem] = mapping_get(elem, 0) + 1
395
396try: # Load C helper function if available
397 from _collections import _count_elements
398except ImportError:
399 pass
400
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000401class Counter(dict):
402 '''Dict subclass for counting hashable items. Sometimes called a bag
403 or multiset. Elements are stored as dictionary keys and their counts
404 are stored as dictionary values.
405
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000406 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000407
408 >>> c.most_common(3) # three most common elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000409 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000410 >>> sorted(c) # list all unique elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000411 ['a', 'b', 'c', 'd', 'e']
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000412 >>> ''.join(sorted(c.elements())) # list elements with repetitions
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000413 'aaaaabbbbcccdde'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000414 >>> sum(c.values()) # total of all counts
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000415 15
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000416
417 >>> c['a'] # count of letter 'a'
418 5
419 >>> for elem in 'shazam': # update counts from an iterable
420 ... c[elem] += 1 # by adding 1 to each element's count
421 >>> c['a'] # now there are seven 'a'
422 7
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000423 >>> del c['b'] # remove all 'b'
424 >>> c['b'] # now there are zero 'b'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000425 0
426
427 >>> d = Counter('simsalabim') # make another counter
428 >>> c.update(d) # add in the second counter
429 >>> c['a'] # now there are nine 'a'
430 9
431
432 >>> c.clear() # empty the counter
433 >>> c
434 Counter()
435
436 Note: If a count is set to zero or reduced to zero, it will remain
437 in the counter until the entry is deleted or the counter is cleared:
438
439 >>> c = Counter('aaabbc')
440 >>> c['b'] -= 2 # reduce the count of 'b' by two
441 >>> c.most_common() # 'b' is still in, but its count is zero
442 [('a', 3), ('c', 1), ('b', 0)]
443
444 '''
445 # References:
446 # http://en.wikipedia.org/wiki/Multiset
447 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
448 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
449 # http://code.activestate.com/recipes/259174/
450 # Knuth, TAOCP Vol. II section 4.6.3
451
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000452 def __init__(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000453 '''Create a new, empty Counter object. And if given, count elements
454 from an input iterable. Or, initialize the count from another mapping
455 of elements to their counts.
456
457 >>> c = Counter() # a new, empty counter
458 >>> c = Counter('gallahad') # a new counter from an iterable
459 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000460 >>> c = Counter(a=4, b=2) # a new counter from keyword args
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000461
462 '''
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000463 super().__init__()
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000464 self.update(iterable, **kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000465
466 def __missing__(self, key):
467 'The count of elements not in the Counter is zero.'
468 # Needed so that self[missing_item] does not raise KeyError
469 return 0
470
471 def most_common(self, n=None):
472 '''List the n most common elements and their counts from the most
473 common to the least. If n is None, then list all element counts.
474
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000475 >>> Counter('abcdeabcdabcaba').most_common(3)
476 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000477
478 '''
479 # Emulate Bag.sortedByCount from Smalltalk
480 if n is None:
481 return sorted(self.items(), key=_itemgetter(1), reverse=True)
482 return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
483
484 def elements(self):
485 '''Iterator over elements repeating each as many times as its count.
486
487 >>> c = Counter('ABCABC')
488 >>> sorted(c.elements())
489 ['A', 'A', 'B', 'B', 'C', 'C']
490
491 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
492 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
493 >>> product = 1
494 >>> for factor in prime_factors.elements(): # loop over factors
495 ... product *= factor # and multiply them
496 >>> product
497 1836
498
499 Note, if an element's count has been set to zero or is a negative
500 number, elements() will ignore it.
501
502 '''
503 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
504 return _chain.from_iterable(_starmap(_repeat, self.items()))
505
506 # Override dict methods where necessary
507
508 @classmethod
509 def fromkeys(cls, iterable, v=None):
510 # There is no equivalent method for counters because setting v=1
511 # means that no element can have a count greater than one.
512 raise NotImplementedError(
513 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
514
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000515 def update(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000516 '''Like dict.update() but add counts instead of replacing them.
517
518 Source can be an iterable, a dictionary, or another Counter instance.
519
520 >>> c = Counter('which')
521 >>> c.update('witch') # add elements from another iterable
522 >>> d = Counter('watch')
523 >>> c.update(d) # add elements from another counter
524 >>> c['h'] # four 'h' in which, witch, and watch
525 4
526
527 '''
528 # The regular dict.update() operation makes no sense here because the
529 # replace behavior results in the some of original untouched counts
530 # being mixed-in with all of the other counts for a mismash that
531 # doesn't have a straight-forward interpretation in most counting
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000532 # contexts. Instead, we implement straight-addition. Both the inputs
533 # and outputs are allowed to contain zero and negative counts.
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000534
535 if iterable is not None:
536 if isinstance(iterable, Mapping):
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000537 if self:
Raymond Hettingerf9092022009-06-29 18:30:43 +0000538 self_get = self.get
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000539 for elem, count in iterable.items():
Raymond Hettingerf9092022009-06-29 18:30:43 +0000540 self[elem] = count + self_get(elem, 0)
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000541 else:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000542 super().update(iterable) # fast path when counter is empty
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000543 else:
Raymond Hettinger96f34102010-12-15 16:30:37 +0000544 _count_elements(self, iterable)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000545 if kwds:
546 self.update(kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000547
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000548 def subtract(self, iterable=None, **kwds):
549 '''Like dict.update() but subtracts counts instead of replacing them.
550 Counts can be reduced below zero. Both the inputs and outputs are
551 allowed to contain zero and negative counts.
552
553 Source can be an iterable, a dictionary, or another Counter instance.
554
555 >>> c = Counter('which')
556 >>> c.subtract('witch') # subtract elements from another iterable
557 >>> c.subtract(Counter('watch')) # subtract elements from another counter
558 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
559 0
560 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
561 -1
562
563 '''
564 if iterable is not None:
Raymond Hettingerfc3c9cd2010-04-11 20:41:56 +0000565 self_get = self.get
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000566 if isinstance(iterable, Mapping):
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000567 for elem, count in iterable.items():
568 self[elem] = self_get(elem, 0) - count
569 else:
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000570 for elem in iterable:
571 self[elem] = self_get(elem, 0) - 1
572 if kwds:
573 self.subtract(kwds)
574
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000575 def copy(self):
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700576 'Return a shallow copy.'
577 return self.__class__(self)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000578
Raymond Hettingerff728162011-01-03 02:44:14 +0000579 def __reduce__(self):
580 return self.__class__, (dict(self),)
581
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000582 def __delitem__(self, elem):
583 'Like dict.__delitem__() but does not raise KeyError for missing values.'
584 if elem in self:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000585 super().__delitem__(elem)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000586
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000587 def __repr__(self):
588 if not self:
589 return '%s()' % self.__class__.__name__
Raymond Hettinger4e6bf412011-11-05 13:35:26 -0700590 try:
591 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
592 return '%s({%s})' % (self.__class__.__name__, items)
593 except TypeError:
594 # handle case where values are not orderable
595 return '{0}({1!r})'.format(self.__class__.__name__, dict(self))
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000596
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000597 # Multiset-style mathematical operations discussed in:
598 # Knuth TAOCP Volume II section 4.6.3 exercise 19
599 # and at http://en.wikipedia.org/wiki/Multiset
600 #
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000601 # Outputs guaranteed to only include positive counts.
602 #
603 # To strip negative and zero counts, add-in an empty counter:
604 # c += Counter()
605
606 def __add__(self, other):
607 '''Add counts from two counters.
608
609 >>> Counter('abbb') + Counter('bcc')
610 Counter({'b': 4, 'c': 2, 'a': 1})
611
612 '''
613 if not isinstance(other, Counter):
614 return NotImplemented
615 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700616 for elem, count in self.items():
617 newcount = count + other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000618 if newcount > 0:
619 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700620 for elem, count in other.items():
621 if elem not in self and count > 0:
622 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000623 return result
624
625 def __sub__(self, other):
626 ''' Subtract count, but keep only results with positive counts.
627
628 >>> Counter('abbbc') - Counter('bccd')
629 Counter({'b': 2, 'a': 1})
630
631 '''
632 if not isinstance(other, Counter):
633 return NotImplemented
634 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700635 for elem, count in self.items():
636 newcount = count - other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000637 if newcount > 0:
638 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700639 for elem, count in other.items():
640 if elem not in self and count < 0:
641 result[elem] = 0 - count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000642 return result
643
644 def __or__(self, other):
645 '''Union is the maximum of value in either of the input counters.
646
647 >>> Counter('abbb') | Counter('bcc')
648 Counter({'b': 3, 'c': 2, 'a': 1})
649
650 '''
651 if not isinstance(other, Counter):
652 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000653 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700654 for elem, count in self.items():
655 other_count = other[elem]
656 newcount = other_count if count < other_count else count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000657 if newcount > 0:
658 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700659 for elem, count in other.items():
660 if elem not in self and count > 0:
661 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000662 return result
663
664 def __and__(self, other):
665 ''' Intersection is the minimum of corresponding counts.
666
667 >>> Counter('abbb') & Counter('bcc')
668 Counter({'b': 1})
669
670 '''
671 if not isinstance(other, Counter):
672 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000673 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700674 for elem, count in self.items():
675 other_count = other[elem]
676 newcount = count if count < other_count else other_count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000677 if newcount > 0:
678 result[elem] = newcount
679 return result
680
Guido van Rossumd8faa362007-04-27 19:54:29 +0000681
Raymond Hettingere6603602011-02-21 19:38:53 +0000682########################################################################
683### ChainMap (helper for configparser)
684########################################################################
685
686class _ChainMap(MutableMapping):
687 ''' A ChainMap groups multiple dicts (or other mappings) together
688 to create a single, updateable view.
689
690 The underlying mappings are stored in a list. That list is public and can
691 accessed or updated using the *maps* attribute. There is no other state.
692
693 Lookups search the underlying mappings successively until a key is found.
694 In contrast, writes, updates, and deletions only operate on the first
695 mapping.
696
697 '''
698
699 def __init__(self, *maps):
700 '''Initialize a ChainMap by setting *maps* to the given mappings.
701 If no mappings are provided, a single empty dictionary is used.
702
703 '''
704 self.maps = list(maps) or [{}] # always at least one map
705
706 def __missing__(self, key):
707 raise KeyError(key)
708
709 def __getitem__(self, key):
710 for mapping in self.maps:
711 try:
712 return mapping[key] # can't use 'key in mapping' with defaultdict
713 except KeyError:
714 pass
715 return self.__missing__(key) # support subclasses that define __missing__
716
717 def get(self, key, default=None):
718 return self[key] if key in self else default
719
720 def __len__(self):
721 return len(set().union(*self.maps)) # reuses stored hash values if possible
722
723 def __iter__(self):
724 return iter(set().union(*self.maps))
725
726 def __contains__(self, key):
727 return any(key in m for m in self.maps)
728
Raymond Hettingera5ac2ce2011-05-02 11:02:13 -0700729 def __bool__(self):
730 return any(self.maps)
731
Raymond Hettingere6603602011-02-21 19:38:53 +0000732 @_recursive_repr()
733 def __repr__(self):
734 return '{0.__class__.__name__}({1})'.format(
735 self, ', '.join(map(repr, self.maps)))
736
737 @classmethod
738 def fromkeys(cls, iterable, *args):
739 'Create a ChainMap with a single dict created from the iterable.'
740 return cls(dict.fromkeys(iterable, *args))
741
742 def copy(self):
743 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
744 return self.__class__(self.maps[0].copy(), *self.maps[1:])
745
746 __copy__ = copy
747
Raymond Hettingerdcb29c92011-02-23 08:28:06 +0000748 def new_child(self): # like Django's Context.push()
749 'New ChainMap with a new dict followed by all previous maps.'
750 return self.__class__({}, *self.maps)
751
752 @property
753 def parents(self): # like Django's Context.pop()
754 'New ChainMap from maps[1:].'
755 return self.__class__(*self.maps[1:])
756
Raymond Hettingere6603602011-02-21 19:38:53 +0000757 def __setitem__(self, key, value):
758 self.maps[0][key] = value
759
760 def __delitem__(self, key):
761 try:
762 del self.maps[0][key]
763 except KeyError:
764 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
765
766 def popitem(self):
767 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
768 try:
769 return self.maps[0].popitem()
770 except KeyError:
771 raise KeyError('No keys found in the first mapping.')
772
773 def pop(self, key, *args):
774 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
775 try:
776 return self.maps[0].pop(key, *args)
777 except KeyError:
778 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
779
780 def clear(self):
781 'Clear maps[0], leaving maps[1:] intact.'
782 self.maps[0].clear()
783
784
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000785################################################################################
786### UserDict
787################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +0000788
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000789class UserDict(MutableMapping):
790
791 # Start by filling-out the abstract methods
792 def __init__(self, dict=None, **kwargs):
793 self.data = {}
794 if dict is not None:
795 self.update(dict)
796 if len(kwargs):
797 self.update(kwargs)
798 def __len__(self): return len(self.data)
799 def __getitem__(self, key):
800 if key in self.data:
801 return self.data[key]
802 if hasattr(self.__class__, "__missing__"):
803 return self.__class__.__missing__(self, key)
804 raise KeyError(key)
805 def __setitem__(self, key, item): self.data[key] = item
806 def __delitem__(self, key): del self.data[key]
807 def __iter__(self):
808 return iter(self.data)
809
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000810 # Modify __contains__ to work correctly when __missing__ is present
811 def __contains__(self, key):
812 return key in self.data
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000813
814 # Now, add the methods in dicts but not in MutableMapping
815 def __repr__(self): return repr(self.data)
816 def copy(self):
817 if self.__class__ is UserDict:
818 return UserDict(self.data.copy())
819 import copy
820 data = self.data
821 try:
822 self.data = {}
823 c = copy.copy(self)
824 finally:
825 self.data = data
826 c.update(self)
827 return c
828 @classmethod
829 def fromkeys(cls, iterable, value=None):
830 d = cls()
831 for key in iterable:
832 d[key] = value
833 return d
834
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000835
836
837################################################################################
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000838### UserList
839################################################################################
840
841class UserList(MutableSequence):
842 """A more or less complete user-defined wrapper around list objects."""
843 def __init__(self, initlist=None):
844 self.data = []
845 if initlist is not None:
846 # XXX should this accept an arbitrary sequence?
847 if type(initlist) == type(self.data):
848 self.data[:] = initlist
849 elif isinstance(initlist, UserList):
850 self.data[:] = initlist.data[:]
851 else:
852 self.data = list(initlist)
853 def __repr__(self): return repr(self.data)
854 def __lt__(self, other): return self.data < self.__cast(other)
855 def __le__(self, other): return self.data <= self.__cast(other)
856 def __eq__(self, other): return self.data == self.__cast(other)
857 def __ne__(self, other): return self.data != self.__cast(other)
858 def __gt__(self, other): return self.data > self.__cast(other)
859 def __ge__(self, other): return self.data >= self.__cast(other)
860 def __cast(self, other):
861 return other.data if isinstance(other, UserList) else other
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000862 def __contains__(self, item): return item in self.data
863 def __len__(self): return len(self.data)
864 def __getitem__(self, i): return self.data[i]
865 def __setitem__(self, i, item): self.data[i] = item
866 def __delitem__(self, i): del self.data[i]
867 def __add__(self, other):
868 if isinstance(other, UserList):
869 return self.__class__(self.data + other.data)
870 elif isinstance(other, type(self.data)):
871 return self.__class__(self.data + other)
872 return self.__class__(self.data + list(other))
873 def __radd__(self, other):
874 if isinstance(other, UserList):
875 return self.__class__(other.data + self.data)
876 elif isinstance(other, type(self.data)):
877 return self.__class__(other + self.data)
878 return self.__class__(list(other) + self.data)
879 def __iadd__(self, other):
880 if isinstance(other, UserList):
881 self.data += other.data
882 elif isinstance(other, type(self.data)):
883 self.data += other
884 else:
885 self.data += list(other)
886 return self
887 def __mul__(self, n):
888 return self.__class__(self.data*n)
889 __rmul__ = __mul__
890 def __imul__(self, n):
891 self.data *= n
892 return self
893 def append(self, item): self.data.append(item)
894 def insert(self, i, item): self.data.insert(i, item)
895 def pop(self, i=-1): return self.data.pop(i)
896 def remove(self, item): self.data.remove(item)
897 def count(self, item): return self.data.count(item)
898 def index(self, item, *args): return self.data.index(item, *args)
899 def reverse(self): self.data.reverse()
900 def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
901 def extend(self, other):
902 if isinstance(other, UserList):
903 self.data.extend(other.data)
904 else:
905 self.data.extend(other)
906
907
908
909################################################################################
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000910### UserString
911################################################################################
912
913class UserString(Sequence):
914 def __init__(self, seq):
915 if isinstance(seq, str):
916 self.data = seq
917 elif isinstance(seq, UserString):
918 self.data = seq.data[:]
919 else:
920 self.data = str(seq)
921 def __str__(self): return str(self.data)
922 def __repr__(self): return repr(self.data)
923 def __int__(self): return int(self.data)
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000924 def __float__(self): return float(self.data)
925 def __complex__(self): return complex(self.data)
926 def __hash__(self): return hash(self.data)
927
928 def __eq__(self, string):
929 if isinstance(string, UserString):
930 return self.data == string.data
931 return self.data == string
932 def __ne__(self, string):
933 if isinstance(string, UserString):
934 return self.data != string.data
935 return self.data != string
936 def __lt__(self, string):
937 if isinstance(string, UserString):
938 return self.data < string.data
939 return self.data < string
940 def __le__(self, string):
941 if isinstance(string, UserString):
942 return self.data <= string.data
943 return self.data <= string
944 def __gt__(self, string):
945 if isinstance(string, UserString):
946 return self.data > string.data
947 return self.data > string
948 def __ge__(self, string):
949 if isinstance(string, UserString):
950 return self.data >= string.data
951 return self.data >= string
952
953 def __contains__(self, char):
954 if isinstance(char, UserString):
955 char = char.data
956 return char in self.data
957
958 def __len__(self): return len(self.data)
959 def __getitem__(self, index): return self.__class__(self.data[index])
960 def __add__(self, other):
961 if isinstance(other, UserString):
962 return self.__class__(self.data + other.data)
963 elif isinstance(other, str):
964 return self.__class__(self.data + other)
965 return self.__class__(self.data + str(other))
966 def __radd__(self, other):
967 if isinstance(other, str):
968 return self.__class__(other + self.data)
969 return self.__class__(str(other) + self.data)
970 def __mul__(self, n):
971 return self.__class__(self.data*n)
972 __rmul__ = __mul__
973 def __mod__(self, args):
974 return self.__class__(self.data % args)
975
976 # the following methods are defined in alphabetical order:
977 def capitalize(self): return self.__class__(self.data.capitalize())
978 def center(self, width, *args):
979 return self.__class__(self.data.center(width, *args))
980 def count(self, sub, start=0, end=_sys.maxsize):
981 if isinstance(sub, UserString):
982 sub = sub.data
983 return self.data.count(sub, start, end)
984 def encode(self, encoding=None, errors=None): # XXX improve this?
985 if encoding:
986 if errors:
987 return self.__class__(self.data.encode(encoding, errors))
988 return self.__class__(self.data.encode(encoding))
989 return self.__class__(self.data.encode())
990 def endswith(self, suffix, start=0, end=_sys.maxsize):
991 return self.data.endswith(suffix, start, end)
992 def expandtabs(self, tabsize=8):
993 return self.__class__(self.data.expandtabs(tabsize))
994 def find(self, sub, start=0, end=_sys.maxsize):
995 if isinstance(sub, UserString):
996 sub = sub.data
997 return self.data.find(sub, start, end)
998 def format(self, *args, **kwds):
999 return self.data.format(*args, **kwds)
1000 def index(self, sub, start=0, end=_sys.maxsize):
1001 return self.data.index(sub, start, end)
1002 def isalpha(self): return self.data.isalpha()
1003 def isalnum(self): return self.data.isalnum()
1004 def isdecimal(self): return self.data.isdecimal()
1005 def isdigit(self): return self.data.isdigit()
1006 def isidentifier(self): return self.data.isidentifier()
1007 def islower(self): return self.data.islower()
1008 def isnumeric(self): return self.data.isnumeric()
1009 def isspace(self): return self.data.isspace()
1010 def istitle(self): return self.data.istitle()
1011 def isupper(self): return self.data.isupper()
1012 def join(self, seq): return self.data.join(seq)
1013 def ljust(self, width, *args):
1014 return self.__class__(self.data.ljust(width, *args))
1015 def lower(self): return self.__class__(self.data.lower())
1016 def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1017 def partition(self, sep):
1018 return self.data.partition(sep)
1019 def replace(self, old, new, maxsplit=-1):
1020 if isinstance(old, UserString):
1021 old = old.data
1022 if isinstance(new, UserString):
1023 new = new.data
1024 return self.__class__(self.data.replace(old, new, maxsplit))
1025 def rfind(self, sub, start=0, end=_sys.maxsize):
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +00001026 if isinstance(sub, UserString):
1027 sub = sub.data
Raymond Hettingerb3a65f82008-02-21 22:11:37 +00001028 return self.data.rfind(sub, start, end)
1029 def rindex(self, sub, start=0, end=_sys.maxsize):
1030 return self.data.rindex(sub, start, end)
1031 def rjust(self, width, *args):
1032 return self.__class__(self.data.rjust(width, *args))
1033 def rpartition(self, sep):
1034 return self.data.rpartition(sep)
1035 def rstrip(self, chars=None):
1036 return self.__class__(self.data.rstrip(chars))
1037 def split(self, sep=None, maxsplit=-1):
1038 return self.data.split(sep, maxsplit)
1039 def rsplit(self, sep=None, maxsplit=-1):
1040 return self.data.rsplit(sep, maxsplit)
1041 def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1042 def startswith(self, prefix, start=0, end=_sys.maxsize):
1043 return self.data.startswith(prefix, start, end)
1044 def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1045 def swapcase(self): return self.__class__(self.data.swapcase())
1046 def title(self): return self.__class__(self.data.title())
1047 def translate(self, *args):
1048 return self.__class__(self.data.translate(*args))
1049 def upper(self): return self.__class__(self.data.upper())
1050 def zfill(self, width): return self.__class__(self.data.zfill(width))
1051
1052
1053
1054################################################################################
Raymond Hettinger48b8b662008-02-05 01:53:00 +00001055### Simple tests
1056################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +00001057
1058if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001059 # verify that instances can be pickled
Guido van Rossum99603b02007-07-20 00:22:32 +00001060 from pickle import loads, dumps
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001061 Point = namedtuple('Point', 'x, y', True)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001062 p = Point(x=10, y=20)
1063 assert p == loads(dumps(p))
1064
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001065 # test and demonstrate ability to override methods
Christian Heimes043d6f62008-01-07 17:19:16 +00001066 class Point(namedtuple('Point', 'x y')):
Christian Heimes25bb7832008-01-11 16:17:00 +00001067 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001068 @property
1069 def hypot(self):
1070 return (self.x ** 2 + self.y ** 2) ** 0.5
Christian Heimes790c8232008-01-07 21:14:23 +00001071 def __str__(self):
Christian Heimes25bb7832008-01-11 16:17:00 +00001072 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
Christian Heimes043d6f62008-01-07 17:19:16 +00001073
Christian Heimes25bb7832008-01-11 16:17:00 +00001074 for p in Point(3, 4), Point(14, 5/7.):
Christian Heimes790c8232008-01-07 21:14:23 +00001075 print (p)
Christian Heimes043d6f62008-01-07 17:19:16 +00001076
1077 class Point(namedtuple('Point', 'x y')):
1078 'Point class with optimized _make() and _replace() without error-checking'
Christian Heimes25bb7832008-01-11 16:17:00 +00001079 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001080 _make = classmethod(tuple.__new__)
1081 def _replace(self, _map=map, **kwds):
Christian Heimes2380ac72008-01-09 00:17:24 +00001082 return self._make(_map(kwds.get, ('x', 'y'), self))
Christian Heimes043d6f62008-01-07 17:19:16 +00001083
1084 print(Point(11, 22)._replace(x=100))
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001085
Christian Heimes25bb7832008-01-11 16:17:00 +00001086 Point3D = namedtuple('Point3D', Point._fields + ('z',))
1087 print(Point3D.__doc__)
1088
Guido van Rossumd8faa362007-04-27 19:54:29 +00001089 import doctest
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001090 TestResults = namedtuple('TestResults', 'failed attempted')
Guido van Rossumd8faa362007-04-27 19:54:29 +00001091 print(TestResults(*doctest.testmod()))