blob: 580b11c969e15f96f5ec46416a203af249437079 [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 Hettingerf1736542009-03-23 05:19:21 +000030 # Big-O running times for all methods are the same as for regular dictionaries.
31
32 # The internal self.__map dictionary maps keys to links in a doubly linked list.
33 # The circular doubly linked list starts and ends with a sentinel element.
34 # The sentinel element never gets deleted (this simplifies the algorithm).
Raymond Hettingerf7328d02010-09-14 19:40:15 +000035 # The sentinel is stored 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 Hettingerf04fa1b2009-04-08 01:15:02 +000041 '''Initialize an ordered dictionary. Signature is the same as for
42 regular dictionaries, but keyword arguments are not recommended
43 because their insertion order is arbitrary.
44
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 Hettingerf1736542009-03-23 05:19:21 +000060 # Setting a new item creates a new link which goes at the end of the linked
61 # list, 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 Hettingerf1736542009-03-23 05:19:21 +000073 # Deleting an existing item uses self.__map to find the link which is
74 # then 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):
172 if key in self:
173 result = self[key]
174 del self[key]
175 return result
176 if default is self.__marker:
177 raise KeyError(key)
178 return default
179
Raymond Hettingera673b1f2010-12-31 23:16:17 +0000180 def setdefault(self, key, default=None):
181 'OD.setdefault(k[,d]) -> OD.get(k,d), also set OD[k]=d if k not in OD'
182 if key in self:
183 return self[key]
184 self[key] = default
185 return default
186
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000187 @_recursive_repr()
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000188 def __repr__(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000189 'od.__repr__() <==> repr(od)'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000190 if not self:
191 return '%s()' % (self.__class__.__name__,)
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000192 return '%s(%r)' % (self.__class__.__name__, list(self.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000193
Raymond Hettingerfc330ae2011-04-20 13:03:49 -0700194 def __reduce__(self):
195 'Return state information for pickling'
196 items = [[k, self[k]] for k in self]
197 inst_dict = vars(self).copy()
198 for k in vars(OrderedDict()):
199 inst_dict.pop(k, None)
200 if inst_dict:
201 return (self.__class__, (items,), inst_dict)
202 return self.__class__, (items,)
203
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000204 def copy(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000205 'od.copy() -> a shallow copy of od'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000206 return self.__class__(self)
207
208 @classmethod
209 def fromkeys(cls, iterable, value=None):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000210 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
211 and values equal to v (which defaults to None).
212
213 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000214 d = cls()
215 for key in iterable:
216 d[key] = value
217 return d
218
219 def __eq__(self, other):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000220 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
221 while comparison to a regular mapping is order-insensitive.
222
223 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000224 if isinstance(other, OrderedDict):
Raymond Hettinger798ee1a2009-03-23 18:29:11 +0000225 return len(self)==len(other) and \
226 all(p==q for p, q in zip(self.items(), other.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000227 return dict.__eq__(self, other)
228
Christian Heimes99170a52007-12-19 02:07:34 +0000229
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000230################################################################################
231### namedtuple
232################################################################################
233
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000234def namedtuple(typename, field_names, verbose=False, rename=False):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000235 """Returns a new subclass of tuple with named fields.
236
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000237 >>> Point = namedtuple('Point', 'x y')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000238 >>> Point.__doc__ # docstring for the new class
Guido van Rossumd8faa362007-04-27 19:54:29 +0000239 'Point(x, y)'
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000240 >>> p = Point(11, y=22) # instantiate with positional args or keywords
Christian Heimes99170a52007-12-19 02:07:34 +0000241 >>> p[0] + p[1] # indexable like a plain tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000242 33
Christian Heimes99170a52007-12-19 02:07:34 +0000243 >>> x, y = p # unpack like a regular tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 >>> x, y
245 (11, 22)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000246 >>> p.x + p.y # fields also accessable by name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000247 33
Christian Heimes0449f632007-12-15 01:27:15 +0000248 >>> d = p._asdict() # convert to a dictionary
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000249 >>> d['x']
250 11
251 >>> Point(**d) # convert from a dictionary
Guido van Rossumd8faa362007-04-27 19:54:29 +0000252 Point(x=11, y=22)
Christian Heimes0449f632007-12-15 01:27:15 +0000253 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000254 Point(x=100, y=22)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000255
256 """
257
Christian Heimes2380ac72008-01-09 00:17:24 +0000258 # Parse and validate the field names. Validation serves two purposes,
259 # generating informative error messages and preventing template injection attacks.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000260 if isinstance(field_names, str):
261 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
Benjamin Petersone9bbc8b2008-09-28 02:06:32 +0000262 field_names = tuple(map(str, field_names))
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000263 if rename:
264 names = list(field_names)
265 seen = set()
266 for i, name in enumerate(names):
267 if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
268 or not name or name[0].isdigit() or name.startswith('_')
269 or name in seen):
Raymond Hettinger56145242009-04-02 22:31:59 +0000270 names[i] = '_%d' % i
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000271 seen.add(name)
272 field_names = tuple(names)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000273 for name in (typename,) + field_names:
Christian Heimesb9eccbf2007-12-05 20:18:38 +0000274 if not all(c.isalnum() or c=='_' for c in name):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000275 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
276 if _iskeyword(name):
277 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
278 if name[0].isdigit():
279 raise ValueError('Type names and field names cannot start with a number: %r' % name)
280 seen_names = set()
281 for name in field_names:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000282 if name.startswith('_') and not rename:
Christian Heimes0449f632007-12-15 01:27:15 +0000283 raise ValueError('Field names cannot start with an underscore: %r' % name)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000284 if name in seen_names:
285 raise ValueError('Encountered duplicate field name: %r' % name)
286 seen_names.add(name)
287
288 # Create and fill-in the class template
Christian Heimesfaf2f632008-01-06 16:59:19 +0000289 numfields = len(field_names)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000290 argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000291 reprtxt = ', '.join('%s=%%r' % name for name in field_names)
292 template = '''class %(typename)s(tuple):
Christian Heimes0449f632007-12-15 01:27:15 +0000293 '%(typename)s(%(argtxt)s)' \n
294 __slots__ = () \n
Christian Heimesfaf2f632008-01-06 16:59:19 +0000295 _fields = %(field_names)r \n
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000296 def __new__(_cls, %(argtxt)s):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000297 'Create new instance of %(typename)s(%(argtxt)s)'
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000298 return _tuple.__new__(_cls, (%(argtxt)s)) \n
Christian Heimesfaf2f632008-01-06 16:59:19 +0000299 @classmethod
Christian Heimes043d6f62008-01-07 17:19:16 +0000300 def _make(cls, iterable, new=tuple.__new__, len=len):
Christian Heimesfaf2f632008-01-06 16:59:19 +0000301 'Make a new %(typename)s object from a sequence or iterable'
Christian Heimes043d6f62008-01-07 17:19:16 +0000302 result = new(cls, iterable)
Christian Heimesfaf2f632008-01-06 16:59:19 +0000303 if len(result) != %(numfields)d:
304 raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
305 return result \n
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000306 def __repr__(self):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000307 'Return a nicely formatted representation string'
Raymond Hettingerd331ce92010-08-08 01:13:42 +0000308 return self.__class__.__name__ + '(%(reprtxt)s)' %% self \n
Raymond Hettingera4f52b12009-03-02 22:28:31 +0000309 def _asdict(self):
310 'Return a new OrderedDict which maps field names to their values'
311 return OrderedDict(zip(self._fields, self)) \n
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000312 def _replace(_self, **kwds):
Guido van Rossum3d392eb2007-11-16 00:35:22 +0000313 'Return a new %(typename)s object replacing specified fields with new values'
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000314 result = _self._make(map(kwds.pop, %(field_names)r, _self))
Christian Heimesfaf2f632008-01-06 16:59:19 +0000315 if kwds:
316 raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000317 return result \n
318 def __getnewargs__(self):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000319 'Return self as a plain tuple. Used by copy and pickle.'
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000320 return tuple(self) \n\n''' % locals()
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000321 for i, name in enumerate(field_names):
Raymond Hettinger7b0d3c62010-04-02 18:54:02 +0000322 template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000323 if verbose:
324 print(template)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000325
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000326 # Execute the template string in a temporary namespace and
327 # support tracing utilities by setting a value for frame.f_globals['__name__']
Raymond Hettinger089ba7f2009-05-27 00:38:24 +0000328 namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
329 OrderedDict=OrderedDict, _property=property, _tuple=tuple)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000330 try:
331 exec(template, namespace)
332 except SyntaxError as e:
Raymond Hettingerc1cc0d02010-09-16 08:06:05 +0000333 raise SyntaxError(e.msg + ':\n\n' + template)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000334 result = namespace[typename]
335
336 # For pickling to work, the __module__ variable needs to be set to the frame
337 # where the named tuple is created. Bypass this step in enviroments where
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000338 # sys._getframe is not defined (Jython for example) or sys._getframe is not
339 # defined for arguments greater than 0 (IronPython).
340 try:
Raymond Hettinger0f055172009-01-27 10:06:09 +0000341 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000342 except (AttributeError, ValueError):
343 pass
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000344
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000345 return result
Guido van Rossumd8faa362007-04-27 19:54:29 +0000346
Guido van Rossumd8faa362007-04-27 19:54:29 +0000347
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000348########################################################################
349### Counter
350########################################################################
351
Raymond Hettinger96f34102010-12-15 16:30:37 +0000352def _count_elements(mapping, iterable):
353 'Tally elements from the iterable.'
354 mapping_get = mapping.get
355 for elem in iterable:
356 mapping[elem] = mapping_get(elem, 0) + 1
357
358try: # Load C helper function if available
359 from _collections import _count_elements
360except ImportError:
361 pass
362
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000363class Counter(dict):
364 '''Dict subclass for counting hashable items. Sometimes called a bag
365 or multiset. Elements are stored as dictionary keys and their counts
366 are stored as dictionary values.
367
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000368 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000369
370 >>> c.most_common(3) # three most common elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000371 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000372 >>> sorted(c) # list all unique elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000373 ['a', 'b', 'c', 'd', 'e']
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000374 >>> ''.join(sorted(c.elements())) # list elements with repetitions
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000375 'aaaaabbbbcccdde'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000376 >>> sum(c.values()) # total of all counts
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000377 15
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000378
379 >>> c['a'] # count of letter 'a'
380 5
381 >>> for elem in 'shazam': # update counts from an iterable
382 ... c[elem] += 1 # by adding 1 to each element's count
383 >>> c['a'] # now there are seven 'a'
384 7
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000385 >>> del c['b'] # remove all 'b'
386 >>> c['b'] # now there are zero 'b'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000387 0
388
389 >>> d = Counter('simsalabim') # make another counter
390 >>> c.update(d) # add in the second counter
391 >>> c['a'] # now there are nine 'a'
392 9
393
394 >>> c.clear() # empty the counter
395 >>> c
396 Counter()
397
398 Note: If a count is set to zero or reduced to zero, it will remain
399 in the counter until the entry is deleted or the counter is cleared:
400
401 >>> c = Counter('aaabbc')
402 >>> c['b'] -= 2 # reduce the count of 'b' by two
403 >>> c.most_common() # 'b' is still in, but its count is zero
404 [('a', 3), ('c', 1), ('b', 0)]
405
406 '''
407 # References:
408 # http://en.wikipedia.org/wiki/Multiset
409 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
410 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
411 # http://code.activestate.com/recipes/259174/
412 # Knuth, TAOCP Vol. II section 4.6.3
413
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000414 def __init__(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000415 '''Create a new, empty Counter object. And if given, count elements
416 from an input iterable. Or, initialize the count from another mapping
417 of elements to their counts.
418
419 >>> c = Counter() # a new, empty counter
420 >>> c = Counter('gallahad') # a new counter from an iterable
421 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000422 >>> c = Counter(a=4, b=2) # a new counter from keyword args
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000423
424 '''
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000425 super().__init__()
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000426 self.update(iterable, **kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000427
428 def __missing__(self, key):
429 'The count of elements not in the Counter is zero.'
430 # Needed so that self[missing_item] does not raise KeyError
431 return 0
432
433 def most_common(self, n=None):
434 '''List the n most common elements and their counts from the most
435 common to the least. If n is None, then list all element counts.
436
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000437 >>> Counter('abcdeabcdabcaba').most_common(3)
438 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000439
440 '''
441 # Emulate Bag.sortedByCount from Smalltalk
442 if n is None:
443 return sorted(self.items(), key=_itemgetter(1), reverse=True)
444 return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
445
446 def elements(self):
447 '''Iterator over elements repeating each as many times as its count.
448
449 >>> c = Counter('ABCABC')
450 >>> sorted(c.elements())
451 ['A', 'A', 'B', 'B', 'C', 'C']
452
453 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
454 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
455 >>> product = 1
456 >>> for factor in prime_factors.elements(): # loop over factors
457 ... product *= factor # and multiply them
458 >>> product
459 1836
460
461 Note, if an element's count has been set to zero or is a negative
462 number, elements() will ignore it.
463
464 '''
465 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
466 return _chain.from_iterable(_starmap(_repeat, self.items()))
467
468 # Override dict methods where necessary
469
470 @classmethod
471 def fromkeys(cls, iterable, v=None):
472 # There is no equivalent method for counters because setting v=1
473 # means that no element can have a count greater than one.
474 raise NotImplementedError(
475 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
476
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000477 def update(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000478 '''Like dict.update() but add counts instead of replacing them.
479
480 Source can be an iterable, a dictionary, or another Counter instance.
481
482 >>> c = Counter('which')
483 >>> c.update('witch') # add elements from another iterable
484 >>> d = Counter('watch')
485 >>> c.update(d) # add elements from another counter
486 >>> c['h'] # four 'h' in which, witch, and watch
487 4
488
489 '''
490 # The regular dict.update() operation makes no sense here because the
491 # replace behavior results in the some of original untouched counts
492 # being mixed-in with all of the other counts for a mismash that
493 # doesn't have a straight-forward interpretation in most counting
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000494 # contexts. Instead, we implement straight-addition. Both the inputs
495 # and outputs are allowed to contain zero and negative counts.
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000496
497 if iterable is not None:
498 if isinstance(iterable, Mapping):
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000499 if self:
Raymond Hettingerf9092022009-06-29 18:30:43 +0000500 self_get = self.get
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000501 for elem, count in iterable.items():
Raymond Hettingerf9092022009-06-29 18:30:43 +0000502 self[elem] = count + self_get(elem, 0)
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000503 else:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000504 super().update(iterable) # fast path when counter is empty
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000505 else:
Raymond Hettinger96f34102010-12-15 16:30:37 +0000506 _count_elements(self, iterable)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000507 if kwds:
508 self.update(kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000509
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000510 def subtract(self, iterable=None, **kwds):
511 '''Like dict.update() but subtracts counts instead of replacing them.
512 Counts can be reduced below zero. Both the inputs and outputs are
513 allowed to contain zero and negative counts.
514
515 Source can be an iterable, a dictionary, or another Counter instance.
516
517 >>> c = Counter('which')
518 >>> c.subtract('witch') # subtract elements from another iterable
519 >>> c.subtract(Counter('watch')) # subtract elements from another counter
520 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
521 0
522 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
523 -1
524
525 '''
526 if iterable is not None:
Raymond Hettingerfc3c9cd2010-04-11 20:41:56 +0000527 self_get = self.get
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000528 if isinstance(iterable, Mapping):
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000529 for elem, count in iterable.items():
530 self[elem] = self_get(elem, 0) - count
531 else:
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000532 for elem in iterable:
533 self[elem] = self_get(elem, 0) - 1
534 if kwds:
535 self.subtract(kwds)
536
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000537 def copy(self):
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700538 'Return a shallow copy.'
539 return self.__class__(self)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000540
Raymond Hettingerff728162011-01-03 02:44:14 +0000541 def __reduce__(self):
542 return self.__class__, (dict(self),)
543
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000544 def __delitem__(self, elem):
545 'Like dict.__delitem__() but does not raise KeyError for missing values.'
546 if elem in self:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000547 super().__delitem__(elem)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000548
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000549 def __repr__(self):
550 if not self:
551 return '%s()' % self.__class__.__name__
552 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
553 return '%s({%s})' % (self.__class__.__name__, items)
554
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000555 # Multiset-style mathematical operations discussed in:
556 # Knuth TAOCP Volume II section 4.6.3 exercise 19
557 # and at http://en.wikipedia.org/wiki/Multiset
558 #
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000559 # Outputs guaranteed to only include positive counts.
560 #
561 # To strip negative and zero counts, add-in an empty counter:
562 # c += Counter()
563
564 def __add__(self, other):
565 '''Add counts from two counters.
566
567 >>> Counter('abbb') + Counter('bcc')
568 Counter({'b': 4, 'c': 2, 'a': 1})
569
570 '''
571 if not isinstance(other, Counter):
572 return NotImplemented
573 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700574 for elem, count in self.items():
575 newcount = count + other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000576 if newcount > 0:
577 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700578 for elem, count in other.items():
579 if elem not in self and count > 0:
580 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000581 return result
582
583 def __sub__(self, other):
584 ''' Subtract count, but keep only results with positive counts.
585
586 >>> Counter('abbbc') - Counter('bccd')
587 Counter({'b': 2, 'a': 1})
588
589 '''
590 if not isinstance(other, Counter):
591 return NotImplemented
592 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700593 for elem, count in self.items():
594 newcount = count - other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000595 if newcount > 0:
596 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700597 for elem, count in other.items():
598 if elem not in self and count < 0:
599 result[elem] = 0 - count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000600 return result
601
602 def __or__(self, other):
603 '''Union is the maximum of value in either of the input counters.
604
605 >>> Counter('abbb') | Counter('bcc')
606 Counter({'b': 3, 'c': 2, 'a': 1})
607
608 '''
609 if not isinstance(other, Counter):
610 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000611 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700612 for elem, count in self.items():
613 other_count = other[elem]
614 newcount = other_count if count < other_count else count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000615 if newcount > 0:
616 result[elem] = newcount
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700617 for elem, count in other.items():
618 if elem not in self and count > 0:
619 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000620 return result
621
622 def __and__(self, other):
623 ''' Intersection is the minimum of corresponding counts.
624
625 >>> Counter('abbb') & Counter('bcc')
626 Counter({'b': 1})
627
628 '''
629 if not isinstance(other, Counter):
630 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000631 result = Counter()
Raymond Hettinger2876a8c2011-04-17 19:46:46 -0700632 for elem, count in self.items():
633 other_count = other[elem]
634 newcount = count if count < other_count else other_count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000635 if newcount > 0:
636 result[elem] = newcount
637 return result
638
Guido van Rossumd8faa362007-04-27 19:54:29 +0000639
Raymond Hettingere6603602011-02-21 19:38:53 +0000640########################################################################
641### ChainMap (helper for configparser)
642########################################################################
643
644class _ChainMap(MutableMapping):
645 ''' A ChainMap groups multiple dicts (or other mappings) together
646 to create a single, updateable view.
647
648 The underlying mappings are stored in a list. That list is public and can
649 accessed or updated using the *maps* attribute. There is no other state.
650
651 Lookups search the underlying mappings successively until a key is found.
652 In contrast, writes, updates, and deletions only operate on the first
653 mapping.
654
655 '''
656
657 def __init__(self, *maps):
658 '''Initialize a ChainMap by setting *maps* to the given mappings.
659 If no mappings are provided, a single empty dictionary is used.
660
661 '''
662 self.maps = list(maps) or [{}] # always at least one map
663
664 def __missing__(self, key):
665 raise KeyError(key)
666
667 def __getitem__(self, key):
668 for mapping in self.maps:
669 try:
670 return mapping[key] # can't use 'key in mapping' with defaultdict
671 except KeyError:
672 pass
673 return self.__missing__(key) # support subclasses that define __missing__
674
675 def get(self, key, default=None):
676 return self[key] if key in self else default
677
678 def __len__(self):
679 return len(set().union(*self.maps)) # reuses stored hash values if possible
680
681 def __iter__(self):
682 return iter(set().union(*self.maps))
683
684 def __contains__(self, key):
685 return any(key in m for m in self.maps)
686
687 @_recursive_repr()
688 def __repr__(self):
689 return '{0.__class__.__name__}({1})'.format(
690 self, ', '.join(map(repr, self.maps)))
691
692 @classmethod
693 def fromkeys(cls, iterable, *args):
694 'Create a ChainMap with a single dict created from the iterable.'
695 return cls(dict.fromkeys(iterable, *args))
696
697 def copy(self):
698 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
699 return self.__class__(self.maps[0].copy(), *self.maps[1:])
700
701 __copy__ = copy
702
Raymond Hettingerdcb29c92011-02-23 08:28:06 +0000703 def new_child(self): # like Django's Context.push()
704 'New ChainMap with a new dict followed by all previous maps.'
705 return self.__class__({}, *self.maps)
706
707 @property
708 def parents(self): # like Django's Context.pop()
709 'New ChainMap from maps[1:].'
710 return self.__class__(*self.maps[1:])
711
Raymond Hettingere6603602011-02-21 19:38:53 +0000712 def __setitem__(self, key, value):
713 self.maps[0][key] = value
714
715 def __delitem__(self, key):
716 try:
717 del self.maps[0][key]
718 except KeyError:
719 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
720
721 def popitem(self):
722 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
723 try:
724 return self.maps[0].popitem()
725 except KeyError:
726 raise KeyError('No keys found in the first mapping.')
727
728 def pop(self, key, *args):
729 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
730 try:
731 return self.maps[0].pop(key, *args)
732 except KeyError:
733 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
734
735 def clear(self):
736 'Clear maps[0], leaving maps[1:] intact.'
737 self.maps[0].clear()
738
739
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000740################################################################################
741### UserDict
742################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +0000743
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000744class UserDict(MutableMapping):
745
746 # Start by filling-out the abstract methods
747 def __init__(self, dict=None, **kwargs):
748 self.data = {}
749 if dict is not None:
750 self.update(dict)
751 if len(kwargs):
752 self.update(kwargs)
753 def __len__(self): return len(self.data)
754 def __getitem__(self, key):
755 if key in self.data:
756 return self.data[key]
757 if hasattr(self.__class__, "__missing__"):
758 return self.__class__.__missing__(self, key)
759 raise KeyError(key)
760 def __setitem__(self, key, item): self.data[key] = item
761 def __delitem__(self, key): del self.data[key]
762 def __iter__(self):
763 return iter(self.data)
764
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000765 # Modify __contains__ to work correctly when __missing__ is present
766 def __contains__(self, key):
767 return key in self.data
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000768
769 # Now, add the methods in dicts but not in MutableMapping
770 def __repr__(self): return repr(self.data)
771 def copy(self):
772 if self.__class__ is UserDict:
773 return UserDict(self.data.copy())
774 import copy
775 data = self.data
776 try:
777 self.data = {}
778 c = copy.copy(self)
779 finally:
780 self.data = data
781 c.update(self)
782 return c
783 @classmethod
784 def fromkeys(cls, iterable, value=None):
785 d = cls()
786 for key in iterable:
787 d[key] = value
788 return d
789
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000790
791
792################################################################################
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000793### UserList
794################################################################################
795
796class UserList(MutableSequence):
797 """A more or less complete user-defined wrapper around list objects."""
798 def __init__(self, initlist=None):
799 self.data = []
800 if initlist is not None:
801 # XXX should this accept an arbitrary sequence?
802 if type(initlist) == type(self.data):
803 self.data[:] = initlist
804 elif isinstance(initlist, UserList):
805 self.data[:] = initlist.data[:]
806 else:
807 self.data = list(initlist)
808 def __repr__(self): return repr(self.data)
809 def __lt__(self, other): return self.data < self.__cast(other)
810 def __le__(self, other): return self.data <= self.__cast(other)
811 def __eq__(self, other): return self.data == self.__cast(other)
812 def __ne__(self, other): return self.data != self.__cast(other)
813 def __gt__(self, other): return self.data > self.__cast(other)
814 def __ge__(self, other): return self.data >= self.__cast(other)
815 def __cast(self, other):
816 return other.data if isinstance(other, UserList) else other
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000817 def __contains__(self, item): return item in self.data
818 def __len__(self): return len(self.data)
819 def __getitem__(self, i): return self.data[i]
820 def __setitem__(self, i, item): self.data[i] = item
821 def __delitem__(self, i): del self.data[i]
822 def __add__(self, other):
823 if isinstance(other, UserList):
824 return self.__class__(self.data + other.data)
825 elif isinstance(other, type(self.data)):
826 return self.__class__(self.data + other)
827 return self.__class__(self.data + list(other))
828 def __radd__(self, other):
829 if isinstance(other, UserList):
830 return self.__class__(other.data + self.data)
831 elif isinstance(other, type(self.data)):
832 return self.__class__(other + self.data)
833 return self.__class__(list(other) + self.data)
834 def __iadd__(self, other):
835 if isinstance(other, UserList):
836 self.data += other.data
837 elif isinstance(other, type(self.data)):
838 self.data += other
839 else:
840 self.data += list(other)
841 return self
842 def __mul__(self, n):
843 return self.__class__(self.data*n)
844 __rmul__ = __mul__
845 def __imul__(self, n):
846 self.data *= n
847 return self
848 def append(self, item): self.data.append(item)
849 def insert(self, i, item): self.data.insert(i, item)
850 def pop(self, i=-1): return self.data.pop(i)
851 def remove(self, item): self.data.remove(item)
852 def count(self, item): return self.data.count(item)
853 def index(self, item, *args): return self.data.index(item, *args)
854 def reverse(self): self.data.reverse()
855 def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
856 def extend(self, other):
857 if isinstance(other, UserList):
858 self.data.extend(other.data)
859 else:
860 self.data.extend(other)
861
862
863
864################################################################################
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000865### UserString
866################################################################################
867
868class UserString(Sequence):
869 def __init__(self, seq):
870 if isinstance(seq, str):
871 self.data = seq
872 elif isinstance(seq, UserString):
873 self.data = seq.data[:]
874 else:
875 self.data = str(seq)
876 def __str__(self): return str(self.data)
877 def __repr__(self): return repr(self.data)
878 def __int__(self): return int(self.data)
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000879 def __float__(self): return float(self.data)
880 def __complex__(self): return complex(self.data)
881 def __hash__(self): return hash(self.data)
882
883 def __eq__(self, string):
884 if isinstance(string, UserString):
885 return self.data == string.data
886 return self.data == string
887 def __ne__(self, string):
888 if isinstance(string, UserString):
889 return self.data != string.data
890 return self.data != string
891 def __lt__(self, string):
892 if isinstance(string, UserString):
893 return self.data < string.data
894 return self.data < string
895 def __le__(self, string):
896 if isinstance(string, UserString):
897 return self.data <= string.data
898 return self.data <= string
899 def __gt__(self, string):
900 if isinstance(string, UserString):
901 return self.data > string.data
902 return self.data > string
903 def __ge__(self, string):
904 if isinstance(string, UserString):
905 return self.data >= string.data
906 return self.data >= string
907
908 def __contains__(self, char):
909 if isinstance(char, UserString):
910 char = char.data
911 return char in self.data
912
913 def __len__(self): return len(self.data)
914 def __getitem__(self, index): return self.__class__(self.data[index])
915 def __add__(self, other):
916 if isinstance(other, UserString):
917 return self.__class__(self.data + other.data)
918 elif isinstance(other, str):
919 return self.__class__(self.data + other)
920 return self.__class__(self.data + str(other))
921 def __radd__(self, other):
922 if isinstance(other, str):
923 return self.__class__(other + self.data)
924 return self.__class__(str(other) + self.data)
925 def __mul__(self, n):
926 return self.__class__(self.data*n)
927 __rmul__ = __mul__
928 def __mod__(self, args):
929 return self.__class__(self.data % args)
930
931 # the following methods are defined in alphabetical order:
932 def capitalize(self): return self.__class__(self.data.capitalize())
933 def center(self, width, *args):
934 return self.__class__(self.data.center(width, *args))
935 def count(self, sub, start=0, end=_sys.maxsize):
936 if isinstance(sub, UserString):
937 sub = sub.data
938 return self.data.count(sub, start, end)
939 def encode(self, encoding=None, errors=None): # XXX improve this?
940 if encoding:
941 if errors:
942 return self.__class__(self.data.encode(encoding, errors))
943 return self.__class__(self.data.encode(encoding))
944 return self.__class__(self.data.encode())
945 def endswith(self, suffix, start=0, end=_sys.maxsize):
946 return self.data.endswith(suffix, start, end)
947 def expandtabs(self, tabsize=8):
948 return self.__class__(self.data.expandtabs(tabsize))
949 def find(self, sub, start=0, end=_sys.maxsize):
950 if isinstance(sub, UserString):
951 sub = sub.data
952 return self.data.find(sub, start, end)
953 def format(self, *args, **kwds):
954 return self.data.format(*args, **kwds)
955 def index(self, sub, start=0, end=_sys.maxsize):
956 return self.data.index(sub, start, end)
957 def isalpha(self): return self.data.isalpha()
958 def isalnum(self): return self.data.isalnum()
959 def isdecimal(self): return self.data.isdecimal()
960 def isdigit(self): return self.data.isdigit()
961 def isidentifier(self): return self.data.isidentifier()
962 def islower(self): return self.data.islower()
963 def isnumeric(self): return self.data.isnumeric()
964 def isspace(self): return self.data.isspace()
965 def istitle(self): return self.data.istitle()
966 def isupper(self): return self.data.isupper()
967 def join(self, seq): return self.data.join(seq)
968 def ljust(self, width, *args):
969 return self.__class__(self.data.ljust(width, *args))
970 def lower(self): return self.__class__(self.data.lower())
971 def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
972 def partition(self, sep):
973 return self.data.partition(sep)
974 def replace(self, old, new, maxsplit=-1):
975 if isinstance(old, UserString):
976 old = old.data
977 if isinstance(new, UserString):
978 new = new.data
979 return self.__class__(self.data.replace(old, new, maxsplit))
980 def rfind(self, sub, start=0, end=_sys.maxsize):
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +0000981 if isinstance(sub, UserString):
982 sub = sub.data
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000983 return self.data.rfind(sub, start, end)
984 def rindex(self, sub, start=0, end=_sys.maxsize):
985 return self.data.rindex(sub, start, end)
986 def rjust(self, width, *args):
987 return self.__class__(self.data.rjust(width, *args))
988 def rpartition(self, sep):
989 return self.data.rpartition(sep)
990 def rstrip(self, chars=None):
991 return self.__class__(self.data.rstrip(chars))
992 def split(self, sep=None, maxsplit=-1):
993 return self.data.split(sep, maxsplit)
994 def rsplit(self, sep=None, maxsplit=-1):
995 return self.data.rsplit(sep, maxsplit)
996 def splitlines(self, keepends=0): return self.data.splitlines(keepends)
997 def startswith(self, prefix, start=0, end=_sys.maxsize):
998 return self.data.startswith(prefix, start, end)
999 def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1000 def swapcase(self): return self.__class__(self.data.swapcase())
1001 def title(self): return self.__class__(self.data.title())
1002 def translate(self, *args):
1003 return self.__class__(self.data.translate(*args))
1004 def upper(self): return self.__class__(self.data.upper())
1005 def zfill(self, width): return self.__class__(self.data.zfill(width))
1006
1007
1008
1009################################################################################
Raymond Hettinger48b8b662008-02-05 01:53:00 +00001010### Simple tests
1011################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +00001012
1013if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001014 # verify that instances can be pickled
Guido van Rossum99603b02007-07-20 00:22:32 +00001015 from pickle import loads, dumps
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001016 Point = namedtuple('Point', 'x, y', True)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001017 p = Point(x=10, y=20)
1018 assert p == loads(dumps(p))
1019
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001020 # test and demonstrate ability to override methods
Christian Heimes043d6f62008-01-07 17:19:16 +00001021 class Point(namedtuple('Point', 'x y')):
Christian Heimes25bb7832008-01-11 16:17:00 +00001022 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001023 @property
1024 def hypot(self):
1025 return (self.x ** 2 + self.y ** 2) ** 0.5
Christian Heimes790c8232008-01-07 21:14:23 +00001026 def __str__(self):
Christian Heimes25bb7832008-01-11 16:17:00 +00001027 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
Christian Heimes043d6f62008-01-07 17:19:16 +00001028
Christian Heimes25bb7832008-01-11 16:17:00 +00001029 for p in Point(3, 4), Point(14, 5/7.):
Christian Heimes790c8232008-01-07 21:14:23 +00001030 print (p)
Christian Heimes043d6f62008-01-07 17:19:16 +00001031
1032 class Point(namedtuple('Point', 'x y')):
1033 'Point class with optimized _make() and _replace() without error-checking'
Christian Heimes25bb7832008-01-11 16:17:00 +00001034 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001035 _make = classmethod(tuple.__new__)
1036 def _replace(self, _map=map, **kwds):
Christian Heimes2380ac72008-01-09 00:17:24 +00001037 return self._make(_map(kwds.get, ('x', 'y'), self))
Christian Heimes043d6f62008-01-07 17:19:16 +00001038
1039 print(Point(11, 22)._replace(x=100))
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001040
Christian Heimes25bb7832008-01-11 16:17:00 +00001041 Point3D = namedtuple('Point3D', Point._fields + ('z',))
1042 print(Point3D.__doc__)
1043
Guido van Rossumd8faa362007-04-27 19:54:29 +00001044 import doctest
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001045 TestResults = namedtuple('TestResults', 'failed attempted')
Guido van Rossumd8faa362007-04-27 19:54:29 +00001046 print(TestResults(*doctest.testmod()))