blob: b9049805558fa5b75031ab4003b7ca7e951558c2 [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
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
271 def _replace(_self, **kwds):
272 'Return a new {typename} object replacing specified fields with new values'
273 result = _self._make(map(kwds.pop, {field_names!r}, _self))
274 if kwds:
275 raise ValueError('Got unexpected field names: %r' % list(kwds))
276 return result
277
278 def __getnewargs__(self):
279 'Return self as a plain tuple. Used by copy and pickle.'
280 return tuple(self)
281
282{field_defs}
283'''
284
285_repr_template = '{name}=%r'
286
287_field_template = '''\
288 {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
289'''
290
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000291def namedtuple(typename, field_names, verbose=False, rename=False):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000292 """Returns a new subclass of tuple with named fields.
293
Raymond Hettinger81b96562011-05-02 09:50:15 -0700294 >>> Point = namedtuple('Point', ['x', 'y'])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000295 >>> Point.__doc__ # docstring for the new class
Guido van Rossumd8faa362007-04-27 19:54:29 +0000296 'Point(x, y)'
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000297 >>> p = Point(11, y=22) # instantiate with positional args or keywords
Christian Heimes99170a52007-12-19 02:07:34 +0000298 >>> p[0] + p[1] # indexable like a plain tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000299 33
Christian Heimes99170a52007-12-19 02:07:34 +0000300 >>> x, y = p # unpack like a regular tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000301 >>> x, y
302 (11, 22)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000303 >>> p.x + p.y # fields also accessable by name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000304 33
Christian Heimes0449f632007-12-15 01:27:15 +0000305 >>> d = p._asdict() # convert to a dictionary
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000306 >>> d['x']
307 11
308 >>> Point(**d) # convert from a dictionary
Guido van Rossumd8faa362007-04-27 19:54:29 +0000309 Point(x=11, y=22)
Christian Heimes0449f632007-12-15 01:27:15 +0000310 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000311 Point(x=100, y=22)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000312
313 """
314
Christian Heimes2380ac72008-01-09 00:17:24 +0000315 # Parse and validate the field names. Validation serves two purposes,
316 # generating informative error messages and preventing template injection attacks.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000317 if isinstance(field_names, str):
318 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
Raymond Hettinger81b96562011-05-02 09:50:15 -0700319 field_names = list(map(str, field_names))
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000320 if rename:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000321 seen = set()
Raymond Hettinger81b96562011-05-02 09:50:15 -0700322 for index, name in enumerate(field_names):
323 if (not all(c.isalnum() or c=='_' for c in name)
324 or _iskeyword(name)
325 or not name
326 or name[0].isdigit()
327 or name.startswith('_')
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000328 or name in seen):
Raymond Hettinger81b96562011-05-02 09:50:15 -0700329 field_names[index] = '_%d' % index
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000330 seen.add(name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700331 for name in [typename] + field_names:
Christian Heimesb9eccbf2007-12-05 20:18:38 +0000332 if not all(c.isalnum() or c=='_' for c in name):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000333 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
334 if _iskeyword(name):
335 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
336 if name[0].isdigit():
337 raise ValueError('Type names and field names cannot start with a number: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700338 seen = set()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000339 for name in field_names:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000340 if name.startswith('_') and not rename:
Christian Heimes0449f632007-12-15 01:27:15 +0000341 raise ValueError('Field names cannot start with an underscore: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700342 if name in seen:
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000343 raise ValueError('Encountered duplicate field name: %r' % name)
Raymond Hettinger81b96562011-05-02 09:50:15 -0700344 seen.add(name)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000345
Raymond Hettinger81b96562011-05-02 09:50:15 -0700346 # Fill-in the class template
347 class_definition = _class_template.format(
348 typename = typename,
349 field_names = tuple(field_names),
350 num_fields = len(field_names),
351 arg_list = repr(tuple(field_names)).replace("'", "")[1:-1],
352 repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names),
353 field_defs = '\n'.join(_field_template.format(index=index, name=name)
354 for index, name in enumerate(field_names))
355 )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000356
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000357 # Execute the template string in a temporary namespace and
358 # support tracing utilities by setting a value for frame.f_globals['__name__']
Raymond Hettinger81b96562011-05-02 09:50:15 -0700359 namespace = dict(__name__='namedtuple_%s' % typename)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000360 try:
Raymond Hettinger81b96562011-05-02 09:50:15 -0700361 exec(class_definition, namespace)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000362 except SyntaxError as e:
Raymond Hettinger81b96562011-05-02 09:50:15 -0700363 raise SyntaxError(e.msg + ':\n\n' + class_definition)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000364 result = namespace[typename]
Raymond Hettinger81b96562011-05-02 09:50:15 -0700365 if verbose:
366 print(class_definition)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000367
368 # For pickling to work, the __module__ variable needs to be set to the frame
369 # where the named tuple is created. Bypass this step in enviroments where
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000370 # sys._getframe is not defined (Jython for example) or sys._getframe is not
371 # defined for arguments greater than 0 (IronPython).
372 try:
Raymond Hettinger0f055172009-01-27 10:06:09 +0000373 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000374 except (AttributeError, ValueError):
375 pass
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000376
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000377 return result
Guido van Rossumd8faa362007-04-27 19:54:29 +0000378
Guido van Rossumd8faa362007-04-27 19:54:29 +0000379
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000380########################################################################
381### Counter
382########################################################################
383
Raymond Hettinger96f34102010-12-15 16:30:37 +0000384def _count_elements(mapping, iterable):
385 'Tally elements from the iterable.'
386 mapping_get = mapping.get
387 for elem in iterable:
388 mapping[elem] = mapping_get(elem, 0) + 1
389
390try: # Load C helper function if available
391 from _collections import _count_elements
392except ImportError:
393 pass
394
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000395class Counter(dict):
396 '''Dict subclass for counting hashable items. Sometimes called a bag
397 or multiset. Elements are stored as dictionary keys and their counts
398 are stored as dictionary values.
399
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000400 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000401
402 >>> c.most_common(3) # three most common elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000403 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000404 >>> sorted(c) # list all unique elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000405 ['a', 'b', 'c', 'd', 'e']
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000406 >>> ''.join(sorted(c.elements())) # list elements with repetitions
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000407 'aaaaabbbbcccdde'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000408 >>> sum(c.values()) # total of all counts
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000409 15
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000410
411 >>> c['a'] # count of letter 'a'
412 5
413 >>> for elem in 'shazam': # update counts from an iterable
414 ... c[elem] += 1 # by adding 1 to each element's count
415 >>> c['a'] # now there are seven 'a'
416 7
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000417 >>> del c['b'] # remove all 'b'
418 >>> c['b'] # now there are zero 'b'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000419 0
420
421 >>> d = Counter('simsalabim') # make another counter
422 >>> c.update(d) # add in the second counter
423 >>> c['a'] # now there are nine 'a'
424 9
425
426 >>> c.clear() # empty the counter
427 >>> c
428 Counter()
429
430 Note: If a count is set to zero or reduced to zero, it will remain
431 in the counter until the entry is deleted or the counter is cleared:
432
433 >>> c = Counter('aaabbc')
434 >>> c['b'] -= 2 # reduce the count of 'b' by two
435 >>> c.most_common() # 'b' is still in, but its count is zero
436 [('a', 3), ('c', 1), ('b', 0)]
437
438 '''
439 # References:
440 # http://en.wikipedia.org/wiki/Multiset
441 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
442 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
443 # http://code.activestate.com/recipes/259174/
444 # Knuth, TAOCP Vol. II section 4.6.3
445
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000446 def __init__(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000447 '''Create a new, empty Counter object. And if given, count elements
448 from an input iterable. Or, initialize the count from another mapping
449 of elements to their counts.
450
451 >>> c = Counter() # a new, empty counter
452 >>> c = Counter('gallahad') # a new counter from an iterable
453 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000454 >>> c = Counter(a=4, b=2) # a new counter from keyword args
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000455
456 '''
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000457 super().__init__()
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000458 self.update(iterable, **kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000459
460 def __missing__(self, key):
461 'The count of elements not in the Counter is zero.'
462 # Needed so that self[missing_item] does not raise KeyError
463 return 0
464
465 def most_common(self, n=None):
466 '''List the n most common elements and their counts from the most
467 common to the least. If n is None, then list all element counts.
468
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000469 >>> Counter('abcdeabcdabcaba').most_common(3)
470 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000471
472 '''
473 # Emulate Bag.sortedByCount from Smalltalk
474 if n is None:
475 return sorted(self.items(), key=_itemgetter(1), reverse=True)
476 return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
477
478 def elements(self):
479 '''Iterator over elements repeating each as many times as its count.
480
481 >>> c = Counter('ABCABC')
482 >>> sorted(c.elements())
483 ['A', 'A', 'B', 'B', 'C', 'C']
484
485 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
486 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
487 >>> product = 1
488 >>> for factor in prime_factors.elements(): # loop over factors
489 ... product *= factor # and multiply them
490 >>> product
491 1836
492
493 Note, if an element's count has been set to zero or is a negative
494 number, elements() will ignore it.
495
496 '''
497 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
498 return _chain.from_iterable(_starmap(_repeat, self.items()))
499
500 # Override dict methods where necessary
501
502 @classmethod
503 def fromkeys(cls, iterable, v=None):
504 # There is no equivalent method for counters because setting v=1
505 # means that no element can have a count greater than one.
506 raise NotImplementedError(
507 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
508
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000509 def update(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000510 '''Like dict.update() but add counts instead of replacing them.
511
512 Source can be an iterable, a dictionary, or another Counter instance.
513
514 >>> c = Counter('which')
515 >>> c.update('witch') # add elements from another iterable
516 >>> d = Counter('watch')
517 >>> c.update(d) # add elements from another counter
518 >>> c['h'] # four 'h' in which, witch, and watch
519 4
520
521 '''
522 # The regular dict.update() operation makes no sense here because the
523 # replace behavior results in the some of original untouched counts
524 # being mixed-in with all of the other counts for a mismash that
525 # doesn't have a straight-forward interpretation in most counting
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000526 # contexts. Instead, we implement straight-addition. Both the inputs
527 # and outputs are allowed to contain zero and negative counts.
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000528
529 if iterable is not None:
530 if isinstance(iterable, Mapping):
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000531 if self:
Raymond Hettingerf9092022009-06-29 18:30:43 +0000532 self_get = self.get
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000533 for elem, count in iterable.items():
Raymond Hettingerf9092022009-06-29 18:30:43 +0000534 self[elem] = count + self_get(elem, 0)
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000535 else:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000536 super().update(iterable) # fast path when counter is empty
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000537 else:
Raymond Hettinger96f34102010-12-15 16:30:37 +0000538 _count_elements(self, iterable)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000539 if kwds:
540 self.update(kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000541
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000542 def subtract(self, iterable=None, **kwds):
543 '''Like dict.update() but subtracts counts instead of replacing them.
544 Counts can be reduced below zero. Both the inputs and outputs are
545 allowed to contain zero and negative counts.
546
547 Source can be an iterable, a dictionary, or another Counter instance.
548
549 >>> c = Counter('which')
550 >>> c.subtract('witch') # subtract elements from another iterable
551 >>> c.subtract(Counter('watch')) # subtract elements from another counter
552 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
553 0
554 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
555 -1
556
557 '''
558 if iterable is not None:
Raymond Hettingerfc3c9cd2010-04-11 20:41:56 +0000559 self_get = self.get
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000560 if isinstance(iterable, Mapping):
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000561 for elem, count in iterable.items():
562 self[elem] = self_get(elem, 0) - count
563 else:
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000564 for elem in iterable:
565 self[elem] = self_get(elem, 0) - 1
566 if kwds:
567 self.subtract(kwds)
568
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000569 def copy(self):
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700570 'Return a shallow copy.'
571 return self.__class__(self)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000572
Raymond Hettingerff728162011-01-03 02:44:14 +0000573 def __reduce__(self):
574 return self.__class__, (dict(self),)
575
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000576 def __delitem__(self, elem):
577 'Like dict.__delitem__() but does not raise KeyError for missing values.'
578 if elem in self:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000579 super().__delitem__(elem)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000580
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000581 def __repr__(self):
582 if not self:
583 return '%s()' % self.__class__.__name__
584 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
585 return '%s({%s})' % (self.__class__.__name__, items)
586
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000587 # Multiset-style mathematical operations discussed in:
588 # Knuth TAOCP Volume II section 4.6.3 exercise 19
589 # and at http://en.wikipedia.org/wiki/Multiset
590 #
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000591 # Outputs guaranteed to only include positive counts.
592 #
593 # To strip negative and zero counts, add-in an empty counter:
594 # c += Counter()
595
596 def __add__(self, other):
597 '''Add counts from two counters.
598
599 >>> Counter('abbb') + Counter('bcc')
600 Counter({'b': 4, 'c': 2, 'a': 1})
601
602 '''
603 if not isinstance(other, Counter):
604 return NotImplemented
605 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700606 for elem, count in self.items():
607 newcount = count + other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000608 if newcount > 0:
609 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700610 for elem, count in other.items():
611 if elem not in self and count > 0:
612 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000613 return result
614
615 def __sub__(self, other):
616 ''' Subtract count, but keep only results with positive counts.
617
618 >>> Counter('abbbc') - Counter('bccd')
619 Counter({'b': 2, 'a': 1})
620
621 '''
622 if not isinstance(other, Counter):
623 return NotImplemented
624 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700625 for elem, count in self.items():
626 newcount = count - other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000627 if newcount > 0:
628 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700629 for elem, count in other.items():
630 if elem not in self and count < 0:
631 result[elem] = 0 - count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000632 return result
633
634 def __or__(self, other):
635 '''Union is the maximum of value in either of the input counters.
636
637 >>> Counter('abbb') | Counter('bcc')
638 Counter({'b': 3, 'c': 2, 'a': 1})
639
640 '''
641 if not isinstance(other, Counter):
642 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000643 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700644 for elem, count in self.items():
645 other_count = other[elem]
646 newcount = other_count if count < other_count else count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000647 if newcount > 0:
648 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700649 for elem, count in other.items():
650 if elem not in self and count > 0:
651 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000652 return result
653
654 def __and__(self, other):
655 ''' Intersection is the minimum of corresponding counts.
656
657 >>> Counter('abbb') & Counter('bcc')
658 Counter({'b': 1})
659
660 '''
661 if not isinstance(other, Counter):
662 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000663 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700664 for elem, count in self.items():
665 other_count = other[elem]
666 newcount = count if count < other_count else other_count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000667 if newcount > 0:
668 result[elem] = newcount
669 return result
670
Guido van Rossumd8faa362007-04-27 19:54:29 +0000671
Raymond Hettingere6603602011-02-21 19:38:53 +0000672########################################################################
673### ChainMap (helper for configparser)
674########################################################################
675
676class _ChainMap(MutableMapping):
677 ''' A ChainMap groups multiple dicts (or other mappings) together
678 to create a single, updateable view.
679
680 The underlying mappings are stored in a list. That list is public and can
681 accessed or updated using the *maps* attribute. There is no other state.
682
683 Lookups search the underlying mappings successively until a key is found.
684 In contrast, writes, updates, and deletions only operate on the first
685 mapping.
686
687 '''
688
689 def __init__(self, *maps):
690 '''Initialize a ChainMap by setting *maps* to the given mappings.
691 If no mappings are provided, a single empty dictionary is used.
692
693 '''
694 self.maps = list(maps) or [{}] # always at least one map
695
696 def __missing__(self, key):
697 raise KeyError(key)
698
699 def __getitem__(self, key):
700 for mapping in self.maps:
701 try:
702 return mapping[key] # can't use 'key in mapping' with defaultdict
703 except KeyError:
704 pass
705 return self.__missing__(key) # support subclasses that define __missing__
706
707 def get(self, key, default=None):
708 return self[key] if key in self else default
709
710 def __len__(self):
711 return len(set().union(*self.maps)) # reuses stored hash values if possible
712
713 def __iter__(self):
714 return iter(set().union(*self.maps))
715
716 def __contains__(self, key):
717 return any(key in m for m in self.maps)
718
Raymond Hettingera5ac2ce2011-05-02 11:02:13 -0700719 def __bool__(self):
720 return any(self.maps)
721
Raymond Hettingere6603602011-02-21 19:38:53 +0000722 @_recursive_repr()
723 def __repr__(self):
724 return '{0.__class__.__name__}({1})'.format(
725 self, ', '.join(map(repr, self.maps)))
726
727 @classmethod
728 def fromkeys(cls, iterable, *args):
729 'Create a ChainMap with a single dict created from the iterable.'
730 return cls(dict.fromkeys(iterable, *args))
731
732 def copy(self):
733 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
734 return self.__class__(self.maps[0].copy(), *self.maps[1:])
735
736 __copy__ = copy
737
Raymond Hettingerdcb29c92011-02-23 08:28:06 +0000738 def new_child(self): # like Django's Context.push()
739 'New ChainMap with a new dict followed by all previous maps.'
740 return self.__class__({}, *self.maps)
741
742 @property
743 def parents(self): # like Django's Context.pop()
744 'New ChainMap from maps[1:].'
745 return self.__class__(*self.maps[1:])
746
Raymond Hettingere6603602011-02-21 19:38:53 +0000747 def __setitem__(self, key, value):
748 self.maps[0][key] = value
749
750 def __delitem__(self, key):
751 try:
752 del self.maps[0][key]
753 except KeyError:
754 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
755
756 def popitem(self):
757 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
758 try:
759 return self.maps[0].popitem()
760 except KeyError:
761 raise KeyError('No keys found in the first mapping.')
762
763 def pop(self, key, *args):
764 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
765 try:
766 return self.maps[0].pop(key, *args)
767 except KeyError:
768 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
769
770 def clear(self):
771 'Clear maps[0], leaving maps[1:] intact.'
772 self.maps[0].clear()
773
774
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000775################################################################################
776### UserDict
777################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +0000778
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000779class UserDict(MutableMapping):
780
781 # Start by filling-out the abstract methods
782 def __init__(self, dict=None, **kwargs):
783 self.data = {}
784 if dict is not None:
785 self.update(dict)
786 if len(kwargs):
787 self.update(kwargs)
788 def __len__(self): return len(self.data)
789 def __getitem__(self, key):
790 if key in self.data:
791 return self.data[key]
792 if hasattr(self.__class__, "__missing__"):
793 return self.__class__.__missing__(self, key)
794 raise KeyError(key)
795 def __setitem__(self, key, item): self.data[key] = item
796 def __delitem__(self, key): del self.data[key]
797 def __iter__(self):
798 return iter(self.data)
799
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000800 # Modify __contains__ to work correctly when __missing__ is present
801 def __contains__(self, key):
802 return key in self.data
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000803
804 # Now, add the methods in dicts but not in MutableMapping
805 def __repr__(self): return repr(self.data)
806 def copy(self):
807 if self.__class__ is UserDict:
808 return UserDict(self.data.copy())
809 import copy
810 data = self.data
811 try:
812 self.data = {}
813 c = copy.copy(self)
814 finally:
815 self.data = data
816 c.update(self)
817 return c
818 @classmethod
819 def fromkeys(cls, iterable, value=None):
820 d = cls()
821 for key in iterable:
822 d[key] = value
823 return d
824
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000825
826
827################################################################################
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000828### UserList
829################################################################################
830
831class UserList(MutableSequence):
832 """A more or less complete user-defined wrapper around list objects."""
833 def __init__(self, initlist=None):
834 self.data = []
835 if initlist is not None:
836 # XXX should this accept an arbitrary sequence?
837 if type(initlist) == type(self.data):
838 self.data[:] = initlist
839 elif isinstance(initlist, UserList):
840 self.data[:] = initlist.data[:]
841 else:
842 self.data = list(initlist)
843 def __repr__(self): return repr(self.data)
844 def __lt__(self, other): return self.data < self.__cast(other)
845 def __le__(self, other): return self.data <= self.__cast(other)
846 def __eq__(self, other): return self.data == self.__cast(other)
847 def __ne__(self, other): return self.data != self.__cast(other)
848 def __gt__(self, other): return self.data > self.__cast(other)
849 def __ge__(self, other): return self.data >= self.__cast(other)
850 def __cast(self, other):
851 return other.data if isinstance(other, UserList) else other
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000852 def __contains__(self, item): return item in self.data
853 def __len__(self): return len(self.data)
854 def __getitem__(self, i): return self.data[i]
855 def __setitem__(self, i, item): self.data[i] = item
856 def __delitem__(self, i): del self.data[i]
857 def __add__(self, other):
858 if isinstance(other, UserList):
859 return self.__class__(self.data + other.data)
860 elif isinstance(other, type(self.data)):
861 return self.__class__(self.data + other)
862 return self.__class__(self.data + list(other))
863 def __radd__(self, other):
864 if isinstance(other, UserList):
865 return self.__class__(other.data + self.data)
866 elif isinstance(other, type(self.data)):
867 return self.__class__(other + self.data)
868 return self.__class__(list(other) + self.data)
869 def __iadd__(self, other):
870 if isinstance(other, UserList):
871 self.data += other.data
872 elif isinstance(other, type(self.data)):
873 self.data += other
874 else:
875 self.data += list(other)
876 return self
877 def __mul__(self, n):
878 return self.__class__(self.data*n)
879 __rmul__ = __mul__
880 def __imul__(self, n):
881 self.data *= n
882 return self
883 def append(self, item): self.data.append(item)
884 def insert(self, i, item): self.data.insert(i, item)
885 def pop(self, i=-1): return self.data.pop(i)
886 def remove(self, item): self.data.remove(item)
887 def count(self, item): return self.data.count(item)
888 def index(self, item, *args): return self.data.index(item, *args)
889 def reverse(self): self.data.reverse()
890 def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
891 def extend(self, other):
892 if isinstance(other, UserList):
893 self.data.extend(other.data)
894 else:
895 self.data.extend(other)
896
897
898
899################################################################################
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000900### UserString
901################################################################################
902
903class UserString(Sequence):
904 def __init__(self, seq):
905 if isinstance(seq, str):
906 self.data = seq
907 elif isinstance(seq, UserString):
908 self.data = seq.data[:]
909 else:
910 self.data = str(seq)
911 def __str__(self): return str(self.data)
912 def __repr__(self): return repr(self.data)
913 def __int__(self): return int(self.data)
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000914 def __float__(self): return float(self.data)
915 def __complex__(self): return complex(self.data)
916 def __hash__(self): return hash(self.data)
917
918 def __eq__(self, string):
919 if isinstance(string, UserString):
920 return self.data == string.data
921 return self.data == string
922 def __ne__(self, string):
923 if isinstance(string, UserString):
924 return self.data != string.data
925 return self.data != string
926 def __lt__(self, string):
927 if isinstance(string, UserString):
928 return self.data < string.data
929 return self.data < string
930 def __le__(self, string):
931 if isinstance(string, UserString):
932 return self.data <= string.data
933 return self.data <= string
934 def __gt__(self, string):
935 if isinstance(string, UserString):
936 return self.data > string.data
937 return self.data > string
938 def __ge__(self, string):
939 if isinstance(string, UserString):
940 return self.data >= string.data
941 return self.data >= string
942
943 def __contains__(self, char):
944 if isinstance(char, UserString):
945 char = char.data
946 return char in self.data
947
948 def __len__(self): return len(self.data)
949 def __getitem__(self, index): return self.__class__(self.data[index])
950 def __add__(self, other):
951 if isinstance(other, UserString):
952 return self.__class__(self.data + other.data)
953 elif isinstance(other, str):
954 return self.__class__(self.data + other)
955 return self.__class__(self.data + str(other))
956 def __radd__(self, other):
957 if isinstance(other, str):
958 return self.__class__(other + self.data)
959 return self.__class__(str(other) + self.data)
960 def __mul__(self, n):
961 return self.__class__(self.data*n)
962 __rmul__ = __mul__
963 def __mod__(self, args):
964 return self.__class__(self.data % args)
965
966 # the following methods are defined in alphabetical order:
967 def capitalize(self): return self.__class__(self.data.capitalize())
968 def center(self, width, *args):
969 return self.__class__(self.data.center(width, *args))
970 def count(self, sub, start=0, end=_sys.maxsize):
971 if isinstance(sub, UserString):
972 sub = sub.data
973 return self.data.count(sub, start, end)
974 def encode(self, encoding=None, errors=None): # XXX improve this?
975 if encoding:
976 if errors:
977 return self.__class__(self.data.encode(encoding, errors))
978 return self.__class__(self.data.encode(encoding))
979 return self.__class__(self.data.encode())
980 def endswith(self, suffix, start=0, end=_sys.maxsize):
981 return self.data.endswith(suffix, start, end)
982 def expandtabs(self, tabsize=8):
983 return self.__class__(self.data.expandtabs(tabsize))
984 def find(self, sub, start=0, end=_sys.maxsize):
985 if isinstance(sub, UserString):
986 sub = sub.data
987 return self.data.find(sub, start, end)
988 def format(self, *args, **kwds):
989 return self.data.format(*args, **kwds)
990 def index(self, sub, start=0, end=_sys.maxsize):
991 return self.data.index(sub, start, end)
992 def isalpha(self): return self.data.isalpha()
993 def isalnum(self): return self.data.isalnum()
994 def isdecimal(self): return self.data.isdecimal()
995 def isdigit(self): return self.data.isdigit()
996 def isidentifier(self): return self.data.isidentifier()
997 def islower(self): return self.data.islower()
998 def isnumeric(self): return self.data.isnumeric()
999 def isspace(self): return self.data.isspace()
1000 def istitle(self): return self.data.istitle()
1001 def isupper(self): return self.data.isupper()
1002 def join(self, seq): return self.data.join(seq)
1003 def ljust(self, width, *args):
1004 return self.__class__(self.data.ljust(width, *args))
1005 def lower(self): return self.__class__(self.data.lower())
1006 def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1007 def partition(self, sep):
1008 return self.data.partition(sep)
1009 def replace(self, old, new, maxsplit=-1):
1010 if isinstance(old, UserString):
1011 old = old.data
1012 if isinstance(new, UserString):
1013 new = new.data
1014 return self.__class__(self.data.replace(old, new, maxsplit))
1015 def rfind(self, sub, start=0, end=_sys.maxsize):
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +00001016 if isinstance(sub, UserString):
1017 sub = sub.data
Raymond Hettingerb3a65f82008-02-21 22:11:37 +00001018 return self.data.rfind(sub, start, end)
1019 def rindex(self, sub, start=0, end=_sys.maxsize):
1020 return self.data.rindex(sub, start, end)
1021 def rjust(self, width, *args):
1022 return self.__class__(self.data.rjust(width, *args))
1023 def rpartition(self, sep):
1024 return self.data.rpartition(sep)
1025 def rstrip(self, chars=None):
1026 return self.__class__(self.data.rstrip(chars))
1027 def split(self, sep=None, maxsplit=-1):
1028 return self.data.split(sep, maxsplit)
1029 def rsplit(self, sep=None, maxsplit=-1):
1030 return self.data.rsplit(sep, maxsplit)
1031 def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1032 def startswith(self, prefix, start=0, end=_sys.maxsize):
1033 return self.data.startswith(prefix, start, end)
1034 def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1035 def swapcase(self): return self.__class__(self.data.swapcase())
1036 def title(self): return self.__class__(self.data.title())
1037 def translate(self, *args):
1038 return self.__class__(self.data.translate(*args))
1039 def upper(self): return self.__class__(self.data.upper())
1040 def zfill(self, width): return self.__class__(self.data.zfill(width))
1041
1042
1043
1044################################################################################
Raymond Hettinger48b8b662008-02-05 01:53:00 +00001045### Simple tests
1046################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +00001047
1048if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001049 # verify that instances can be pickled
Guido van Rossum99603b02007-07-20 00:22:32 +00001050 from pickle import loads, dumps
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001051 Point = namedtuple('Point', 'x, y', True)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001052 p = Point(x=10, y=20)
1053 assert p == loads(dumps(p))
1054
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001055 # test and demonstrate ability to override methods
Christian Heimes043d6f62008-01-07 17:19:16 +00001056 class Point(namedtuple('Point', 'x y')):
Christian Heimes25bb7832008-01-11 16:17:00 +00001057 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001058 @property
1059 def hypot(self):
1060 return (self.x ** 2 + self.y ** 2) ** 0.5
Christian Heimes790c8232008-01-07 21:14:23 +00001061 def __str__(self):
Christian Heimes25bb7832008-01-11 16:17:00 +00001062 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
Christian Heimes043d6f62008-01-07 17:19:16 +00001063
Christian Heimes25bb7832008-01-11 16:17:00 +00001064 for p in Point(3, 4), Point(14, 5/7.):
Christian Heimes790c8232008-01-07 21:14:23 +00001065 print (p)
Christian Heimes043d6f62008-01-07 17:19:16 +00001066
1067 class Point(namedtuple('Point', 'x y')):
1068 'Point class with optimized _make() and _replace() without error-checking'
Christian Heimes25bb7832008-01-11 16:17:00 +00001069 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001070 _make = classmethod(tuple.__new__)
1071 def _replace(self, _map=map, **kwds):
Christian Heimes2380ac72008-01-09 00:17:24 +00001072 return self._make(_map(kwds.get, ('x', 'y'), self))
Christian Heimes043d6f62008-01-07 17:19:16 +00001073
1074 print(Point(11, 22)._replace(x=100))
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001075
Christian Heimes25bb7832008-01-11 16:17:00 +00001076 Point3D = namedtuple('Point3D', Point._fields + ('z',))
1077 print(Point3D.__doc__)
1078
Guido van Rossumd8faa362007-04-27 19:54:29 +00001079 import doctest
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001080 TestResults = namedtuple('TestResults', 'failed attempted')
Guido van Rossumd8faa362007-04-27 19:54:29 +00001081 print(TestResults(*doctest.testmod()))