blob: 03bd2b31ec1cd73bcfbdca90c339da75e2dcd0b8 [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']
Raymond Hettinger158c9c22011-02-22 00:41:50 +00003
Ezio Melotti37308922011-03-15 06:03:08 +02004# For backwards compatibility, continue to make the collections ABCs
Raymond Hettinger158c9c22011-02-22 00:41:50 +00005# available through the collections module.
6from collections.abc import *
7import collections.abc
8__all__ += collections.abc.__all__
Guido van Rossumcd16bf62007-06-13 18:07:49 +00009
Christian Heimes99170a52007-12-19 02:07:34 +000010from _collections import deque, defaultdict
11from operator import itemgetter as _itemgetter
12from keyword import iskeyword as _iskeyword
13import sys as _sys
Raymond Hettingerb8baf632009-01-14 02:20:07 +000014import heapq as _heapq
Raymond Hettingerfa11db02010-09-12 04:12:42 +000015from weakref import proxy as _proxy
Raymond Hettingerea9f8db2009-03-02 21:28:41 +000016from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +000017from reprlib import recursive_repr as _recursive_repr
Raymond Hettinger2d32f632009-03-02 21:24:57 +000018
19################################################################################
20### OrderedDict
21################################################################################
22
Raymond Hettingerfa11db02010-09-12 04:12:42 +000023class _Link(object):
24 __slots__ = 'prev', 'next', 'key', '__weakref__'
25
Raymond Hettinger345c49b2011-01-01 23:51:55 +000026class OrderedDict(dict):
Raymond Hettinger18ed2cb2009-03-19 23:14:39 +000027 'Dictionary that remembers insertion order'
Raymond Hettingerf1736542009-03-23 05:19:21 +000028 # An inherited dict maps keys to values.
Raymond Hettinger18ed2cb2009-03-19 23:14:39 +000029 # The inherited dict provides __getitem__, __len__, __contains__, and get.
30 # The remaining methods are order-aware.
Raymond Hettingera82aa552011-04-24 14:34:26 -070031 # Big-O running times for all methods are the same as regular dictionaries.
Raymond Hettingerf1736542009-03-23 05:19:21 +000032
Raymond Hettingera82aa552011-04-24 14:34:26 -070033 # The internal self.__map dict maps keys to links in a doubly linked list.
Raymond Hettingerf1736542009-03-23 05:19:21 +000034 # The circular doubly linked list starts and ends with a sentinel element.
35 # The sentinel element never gets deleted (this simplifies the algorithm).
Raymond Hettingera82aa552011-04-24 14:34:26 -070036 # The sentinel is in self.__hardroot with a weakref proxy in self.__root.
Raymond Hettingerc5c29c02010-09-12 18:13:46 +000037 # The prev/next links are weakref proxies (to prevent circular references).
38 # Individual links are kept alive by the hard reference in self.__map.
39 # Those hard references disappear when a key is deleted from an OrderedDict.
Raymond Hettinger2d32f632009-03-02 21:24:57 +000040
41 def __init__(self, *args, **kwds):
Raymond Hettingera82aa552011-04-24 14:34:26 -070042 '''Initialize an ordered dictionary. The signature is the same as
43 regular dictionaries, but keyword arguments are not recommended because
44 their insertion order is arbitrary.
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000045
46 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +000047 if len(args) > 1:
48 raise TypeError('expected at most 1 arguments, got %d' % len(args))
Raymond Hettinger08c70cf2009-03-03 20:47:29 +000049 try:
Raymond Hettingerf1736542009-03-23 05:19:21 +000050 self.__root
Raymond Hettinger08c70cf2009-03-03 20:47:29 +000051 except AttributeError:
Raymond Hettingerf7328d02010-09-14 19:40:15 +000052 self.__hardroot = _Link()
53 self.__root = root = _proxy(self.__hardroot)
Raymond Hettingerfa11db02010-09-12 04:12:42 +000054 root.prev = root.next = root
Raymond Hettinger52dc06b2009-03-25 22:45:22 +000055 self.__map = {}
Raymond Hettinger32062e92011-01-01 22:38:00 +000056 self.__update(*args, **kwds)
Raymond Hettinger2d32f632009-03-02 21:24:57 +000057
Raymond Hettingerfa11db02010-09-12 04:12:42 +000058 def __setitem__(self, key, value,
59 dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000060 'od.__setitem__(i, y) <==> od[i]=y'
Raymond Hettingera82aa552011-04-24 14:34:26 -070061 # Setting a new item creates a new link at the end of the linked list,
62 # and the inherited dictionary is updated with the new key/value pair.
Raymond Hettinger2d32f632009-03-02 21:24:57 +000063 if key not in self:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000064 self.__map[key] = link = Link()
Raymond Hettingerf1736542009-03-23 05:19:21 +000065 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000066 last = root.prev
67 link.prev, link.next, link.key = last, root, key
Raymond Hettingerf7328d02010-09-14 19:40:15 +000068 last.next = link
69 root.prev = proxy(link)
70 dict_setitem(self, key, value)
Raymond Hettinger2d32f632009-03-02 21:24:57 +000071
Raymond Hettingerfa11db02010-09-12 04:12:42 +000072 def __delitem__(self, key, dict_delitem=dict.__delitem__):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000073 'od.__delitem__(y) <==> del od[y]'
Raymond Hettingera82aa552011-04-24 14:34:26 -070074 # Deleting an existing item uses self.__map to find the link which gets
75 # removed by updating the links in the predecessor and successor nodes.
Raymond Hettinger5be21b72010-08-01 22:10:57 +000076 dict_delitem(self, key)
Raymond Hettingerf1736542009-03-23 05:19:21 +000077 link = self.__map.pop(key)
Raymond Hettingerfa11db02010-09-12 04:12:42 +000078 link_prev = link.prev
79 link_next = link.next
80 link_prev.next = link_next
81 link_next.prev = link_prev
Raymond Hettinger2d32f632009-03-02 21:24:57 +000082
Raymond Hettingerfa11db02010-09-12 04:12:42 +000083 def __iter__(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +000084 'od.__iter__() <==> iter(od)'
Raymond Hettingerf1736542009-03-23 05:19:21 +000085 # Traverse the linked list in order.
86 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000087 curr = root.next
Raymond Hettingerf1736542009-03-23 05:19:21 +000088 while curr is not root:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000089 yield curr.key
90 curr = curr.next
Raymond Hettinger2d32f632009-03-02 21:24:57 +000091
Raymond Hettingerfa11db02010-09-12 04:12:42 +000092 def __reversed__(self):
Raymond Hettinger2352cf32009-04-08 01:16:27 +000093 'od.__reversed__() <==> reversed(od)'
Raymond Hettingerf1736542009-03-23 05:19:21 +000094 # Traverse the linked list in reverse order.
95 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +000096 curr = root.prev
Raymond Hettingerf1736542009-03-23 05:19:21 +000097 while curr is not root:
Raymond Hettingerfa11db02010-09-12 04:12:42 +000098 yield curr.key
99 curr = curr.prev
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000100
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000101 def clear(self):
102 'od.clear() -> None. Remove all items from od.'
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000103 root = self.__root
104 root.prev = root.next = root
105 self.__map.clear()
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000106 dict.clear(self)
107
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000108 def popitem(self, last=True):
Raymond Hettinger331722d2010-09-02 18:44:16 +0000109 '''od.popitem() -> (k, v), return and remove a (key, value) pair.
110 Pairs are returned in LIFO order if last is true or FIFO order if false.
111
112 '''
113 if not self:
114 raise KeyError('dictionary is empty')
115 root = self.__root
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000116 if last:
117 link = root.prev
118 link_prev = link.prev
119 link_prev.next = root
120 root.prev = link_prev
121 else:
122 link = root.next
123 link_next = link.next
124 root.next = link_next
125 link_next.prev = root
126 key = link.key
Raymond Hettinger331722d2010-09-02 18:44:16 +0000127 del self.__map[key]
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000128 value = dict.pop(self, key)
Raymond Hettinger331722d2010-09-02 18:44:16 +0000129 return key, value
130
Raymond Hettingerfa11db02010-09-12 04:12:42 +0000131 def move_to_end(self, key, last=True):
132 '''Move an existing element to the end (or beginning if last==False).
133
134 Raises KeyError if the element does not exist.
135 When last=True, acts like a fast version of self[key]=self.pop(key).
136
137 '''
138 link = self.__map[key]
139 link_prev = link.prev
140 link_next = link.next
141 link_prev.next = link_next
142 link_next.prev = link_prev
143 root = self.__root
144 if last:
145 last = root.prev
146 link.prev = last
147 link.next = root
148 last.next = root.prev = link
149 else:
150 first = root.next
151 link.prev = root
152 link.next = first
153 root.next = first.prev = link
154
Raymond Hettinger35c87f22010-09-16 19:10:17 +0000155 def __sizeof__(self):
156 sizeof = _sys.getsizeof
157 n = len(self) + 1 # number of links including root
158 size = sizeof(self.__dict__) # instance dictionary
159 size += sizeof(self.__map) * 2 # internal dict and inherited dict
160 size += sizeof(self.__hardroot) * n # link objects
161 size += sizeof(self.__root) * n # proxy objects
162 return size
163
Raymond Hettinger32062e92011-01-01 22:38:00 +0000164 update = __update = MutableMapping.update
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000165 keys = MutableMapping.keys
166 values = MutableMapping.values
167 items = MutableMapping.items
Raymond Hettinger5be21b72010-08-01 22:10:57 +0000168 __ne__ = MutableMapping.__ne__
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000169
Raymond Hettinger345c49b2011-01-01 23:51:55 +0000170 __marker = object()
171
172 def pop(self, key, default=__marker):
Raymond Hettingera82aa552011-04-24 14:34:26 -0700173 '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
174 value. If key is not found, d is returned if given, otherwise KeyError
175 is raised.
176
177 '''
Raymond Hettinger345c49b2011-01-01 23:51:55 +0000178 if key in self:
179 result = self[key]
180 del self[key]
181 return result
182 if default is self.__marker:
183 raise KeyError(key)
184 return default
185
Raymond Hettingera673b1f2010-12-31 23:16:17 +0000186 def setdefault(self, key, default=None):
Raymond Hettingera82aa552011-04-24 14:34:26 -0700187 '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 +0000188 if key in self:
189 return self[key]
190 self[key] = default
191 return default
192
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000193 @_recursive_repr()
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000194 def __repr__(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000195 'od.__repr__() <==> repr(od)'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000196 if not self:
197 return '%s()' % (self.__class__.__name__,)
Raymond Hettinger98a5f3f2010-09-13 21:36:00 +0000198 return '%s(%r)' % (self.__class__.__name__, list(self.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000199
Raymond Hettingerfc330ae2011-04-20 13:03:49 -0700200 def __reduce__(self):
201 'Return state information for pickling'
202 items = [[k, self[k]] for k in self]
203 inst_dict = vars(self).copy()
204 for k in vars(OrderedDict()):
205 inst_dict.pop(k, None)
206 if inst_dict:
207 return (self.__class__, (items,), inst_dict)
208 return self.__class__, (items,)
209
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000210 def copy(self):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000211 'od.copy() -> a shallow copy of od'
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000212 return self.__class__(self)
213
214 @classmethod
215 def fromkeys(cls, iterable, value=None):
Raymond Hettingera82aa552011-04-24 14:34:26 -0700216 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
217 If not specified, the value defaults to None.
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000218
219 '''
Raymond Hettingera82aa552011-04-24 14:34:26 -0700220 self = cls()
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000221 for key in iterable:
Raymond Hettingera82aa552011-04-24 14:34:26 -0700222 self[key] = value
223 return self
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000224
225 def __eq__(self, other):
Raymond Hettingerf04fa1b2009-04-08 01:15:02 +0000226 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
227 while comparison to a regular mapping is order-insensitive.
228
229 '''
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000230 if isinstance(other, OrderedDict):
Raymond Hettinger798ee1a2009-03-23 18:29:11 +0000231 return len(self)==len(other) and \
232 all(p==q for p, q in zip(self.items(), other.items()))
Raymond Hettinger2d32f632009-03-02 21:24:57 +0000233 return dict.__eq__(self, other)
234
Christian Heimes99170a52007-12-19 02:07:34 +0000235
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000236################################################################################
237### namedtuple
238################################################################################
239
Raymond Hettingerfef85462011-03-22 21:14:41 -0700240_class_template = '''\
Raymond Hettinger843a7512011-03-23 11:49:56 -0700241from builtins import property as _property, tuple as _tuple
242from operator import itemgetter as _itemgetter
243from collections import OrderedDict
244
Raymond Hettingerfef85462011-03-22 21:14:41 -0700245class {typename}(tuple):
246 '{typename}({arg_list})'
247
248 __slots__ = ()
249
250 _fields = {field_names!r}
251
252 def __new__(_cls, {arg_list}):
253 'Create new instance of {typename}({arg_list})'
254 return _tuple.__new__(_cls, ({arg_list}))
255
256 @classmethod
257 def _make(cls, iterable, new=tuple.__new__, len=len):
258 'Make a new {typename} object from a sequence or iterable'
259 result = new(cls, iterable)
260 if len(result) != {num_fields:d}:
261 raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result))
262 return result
263
264 def __repr__(self):
265 'Return a nicely formatted representation string'
266 return self.__class__.__name__ + '({repr_fmt})' % self
267
268 def _asdict(self):
269 'Return a new OrderedDict which maps field names to their values'
270 return OrderedDict(zip(self._fields, self))
271
Raymond Hettinger3d890572011-06-02 23:40:24 -0700272 __dict__ = property(_asdict)
273
Raymond Hettingerfef85462011-03-22 21:14:41 -0700274 def _replace(_self, **kwds):
275 'Return a new {typename} object replacing specified fields with new values'
276 result = _self._make(map(kwds.pop, {field_names!r}, _self))
277 if kwds:
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700278 raise ValueError('Got unexpected field names: %r' % list(kwds))
Raymond Hettingerfef85462011-03-22 21:14:41 -0700279 return result
280
281 def __getnewargs__(self):
282 'Return self as a plain tuple. Used by copy and pickle.'
283 return tuple(self)
284
285{field_defs}
286'''
287
288_repr_template = '{name}=%r'
289
290_field_template = '''\
291 {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
292'''
293
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000294def namedtuple(typename, field_names, verbose=False, rename=False):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000295 """Returns a new subclass of tuple with named fields.
296
Raymond Hettingerfef85462011-03-22 21:14:41 -0700297 >>> Point = namedtuple('Point', ['x', 'y'])
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000298 >>> Point.__doc__ # docstring for the new class
Guido van Rossumd8faa362007-04-27 19:54:29 +0000299 'Point(x, y)'
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000300 >>> p = Point(11, y=22) # instantiate with positional args or keywords
Christian Heimes99170a52007-12-19 02:07:34 +0000301 >>> p[0] + p[1] # indexable like a plain tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000302 33
Christian Heimes99170a52007-12-19 02:07:34 +0000303 >>> x, y = p # unpack like a regular tuple
Guido van Rossumd8faa362007-04-27 19:54:29 +0000304 >>> x, y
305 (11, 22)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000306 >>> p.x + p.y # fields also accessable by name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000307 33
Christian Heimes0449f632007-12-15 01:27:15 +0000308 >>> d = p._asdict() # convert to a dictionary
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000309 >>> d['x']
310 11
311 >>> Point(**d) # convert from a dictionary
Guido van Rossumd8faa362007-04-27 19:54:29 +0000312 Point(x=11, y=22)
Christian Heimes0449f632007-12-15 01:27:15 +0000313 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000314 Point(x=100, y=22)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000315
316 """
317
Christian Heimes2380ac72008-01-09 00:17:24 +0000318 # Parse and validate the field names. Validation serves two purposes,
319 # generating informative error messages and preventing template injection attacks.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000320 if isinstance(field_names, str):
321 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700322 field_names = list(map(str, field_names))
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000323 if rename:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000324 seen = set()
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700325 for index, name in enumerate(field_names):
326 if (not all(c.isalnum() or c=='_' for c in name)
327 or _iskeyword(name)
Raymond Hettinger15d0c1d2011-03-23 14:38:39 -0700328 or not name
329 or name[0].isdigit()
330 or name.startswith('_')
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000331 or name in seen):
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700332 field_names[index] = '_%d' % index
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000333 seen.add(name)
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700334 for name in [typename] + field_names:
Christian Heimesb9eccbf2007-12-05 20:18:38 +0000335 if not all(c.isalnum() or c=='_' for c in name):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000336 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
337 if _iskeyword(name):
338 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
339 if name[0].isdigit():
340 raise ValueError('Type names and field names cannot start with a number: %r' % name)
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700341 seen = set()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000342 for name in field_names:
Benjamin Petersona86f2c02009-02-10 02:41:10 +0000343 if name.startswith('_') and not rename:
Christian Heimes0449f632007-12-15 01:27:15 +0000344 raise ValueError('Field names cannot start with an underscore: %r' % name)
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700345 if name in seen:
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000346 raise ValueError('Encountered duplicate field name: %r' % name)
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700347 seen.add(name)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000348
Raymond Hettingerfef85462011-03-22 21:14:41 -0700349 # Fill-in the class template
350 class_definition = _class_template.format(
Raymond Hettinger3e82ae02011-03-22 14:21:38 -0700351 typename = typename,
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700352 field_names = tuple(field_names),
Raymond Hettingerfef85462011-03-22 21:14:41 -0700353 num_fields = len(field_names),
Raymond Hettingerb2d09452011-03-22 22:36:21 -0700354 arg_list = repr(tuple(field_names)).replace("'", "")[1:-1],
Raymond Hettingerfef85462011-03-22 21:14:41 -0700355 repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names),
356 field_defs = '\n'.join(_field_template.format(index=index, name=name)
357 for index, name in enumerate(field_names))
Raymond Hettinger3e82ae02011-03-22 14:21:38 -0700358 )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000359
Raymond Hettingerf6d3e8e2011-03-23 20:33:30 -0700360 # Execute the template string in a temporary namespace and
361 # support tracing utilities by setting a value for frame.f_globals['__name__']
362 namespace = dict(__name__='namedtuple_%s' % typename)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000363 try:
Raymond Hettingerfef85462011-03-22 21:14:41 -0700364 exec(class_definition, namespace)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000365 except SyntaxError as e:
Raymond Hettingerfef85462011-03-22 21:14:41 -0700366 raise SyntaxError(e.msg + ':\n\n' + class_definition)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000367 result = namespace[typename]
Raymond Hettinger2ebea412011-03-23 12:52:23 -0700368 result._source = class_definition
369 if verbose:
370 print(result._source)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000371
372 # For pickling to work, the __module__ variable needs to be set to the frame
373 # where the named tuple is created. Bypass this step in enviroments where
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000374 # sys._getframe is not defined (Jython for example) or sys._getframe is not
375 # defined for arguments greater than 0 (IronPython).
376 try:
Raymond Hettinger0f055172009-01-27 10:06:09 +0000377 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000378 except (AttributeError, ValueError):
379 pass
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000380
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000381 return result
Guido van Rossumd8faa362007-04-27 19:54:29 +0000382
Guido van Rossumd8faa362007-04-27 19:54:29 +0000383
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000384########################################################################
385### Counter
386########################################################################
387
Raymond Hettinger96f34102010-12-15 16:30:37 +0000388def _count_elements(mapping, iterable):
389 'Tally elements from the iterable.'
390 mapping_get = mapping.get
391 for elem in iterable:
392 mapping[elem] = mapping_get(elem, 0) + 1
393
394try: # Load C helper function if available
395 from _collections import _count_elements
396except ImportError:
397 pass
398
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000399class Counter(dict):
400 '''Dict subclass for counting hashable items. Sometimes called a bag
401 or multiset. Elements are stored as dictionary keys and their counts
402 are stored as dictionary values.
403
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000404 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000405
406 >>> c.most_common(3) # three most common elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000407 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000408 >>> sorted(c) # list all unique elements
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000409 ['a', 'b', 'c', 'd', 'e']
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000410 >>> ''.join(sorted(c.elements())) # list elements with repetitions
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000411 'aaaaabbbbcccdde'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000412 >>> sum(c.values()) # total of all counts
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000413 15
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000414
415 >>> c['a'] # count of letter 'a'
416 5
417 >>> for elem in 'shazam': # update counts from an iterable
418 ... c[elem] += 1 # by adding 1 to each element's count
419 >>> c['a'] # now there are seven 'a'
420 7
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000421 >>> del c['b'] # remove all 'b'
422 >>> c['b'] # now there are zero 'b'
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000423 0
424
425 >>> d = Counter('simsalabim') # make another counter
426 >>> c.update(d) # add in the second counter
427 >>> c['a'] # now there are nine 'a'
428 9
429
430 >>> c.clear() # empty the counter
431 >>> c
432 Counter()
433
434 Note: If a count is set to zero or reduced to zero, it will remain
435 in the counter until the entry is deleted or the counter is cleared:
436
437 >>> c = Counter('aaabbc')
438 >>> c['b'] -= 2 # reduce the count of 'b' by two
439 >>> c.most_common() # 'b' is still in, but its count is zero
440 [('a', 3), ('c', 1), ('b', 0)]
441
442 '''
443 # References:
444 # http://en.wikipedia.org/wiki/Multiset
445 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
446 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
447 # http://code.activestate.com/recipes/259174/
448 # Knuth, TAOCP Vol. II section 4.6.3
449
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000450 def __init__(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000451 '''Create a new, empty Counter object. And if given, count elements
452 from an input iterable. Or, initialize the count from another mapping
453 of elements to their counts.
454
455 >>> c = Counter() # a new, empty counter
456 >>> c = Counter('gallahad') # a new counter from an iterable
457 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000458 >>> c = Counter(a=4, b=2) # a new counter from keyword args
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000459
460 '''
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000461 super().__init__()
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000462 self.update(iterable, **kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000463
464 def __missing__(self, key):
465 'The count of elements not in the Counter is zero.'
466 # Needed so that self[missing_item] does not raise KeyError
467 return 0
468
469 def most_common(self, n=None):
470 '''List the n most common elements and their counts from the most
471 common to the least. If n is None, then list all element counts.
472
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000473 >>> Counter('abcdeabcdabcaba').most_common(3)
474 [('a', 5), ('b', 4), ('c', 3)]
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000475
476 '''
477 # Emulate Bag.sortedByCount from Smalltalk
478 if n is None:
479 return sorted(self.items(), key=_itemgetter(1), reverse=True)
480 return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
481
482 def elements(self):
483 '''Iterator over elements repeating each as many times as its count.
484
485 >>> c = Counter('ABCABC')
486 >>> sorted(c.elements())
487 ['A', 'A', 'B', 'B', 'C', 'C']
488
489 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
490 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
491 >>> product = 1
492 >>> for factor in prime_factors.elements(): # loop over factors
493 ... product *= factor # and multiply them
494 >>> product
495 1836
496
497 Note, if an element's count has been set to zero or is a negative
498 number, elements() will ignore it.
499
500 '''
501 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
502 return _chain.from_iterable(_starmap(_repeat, self.items()))
503
504 # Override dict methods where necessary
505
506 @classmethod
507 def fromkeys(cls, iterable, v=None):
508 # There is no equivalent method for counters because setting v=1
509 # means that no element can have a count greater than one.
510 raise NotImplementedError(
511 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
512
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000513 def update(self, iterable=None, **kwds):
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000514 '''Like dict.update() but add counts instead of replacing them.
515
516 Source can be an iterable, a dictionary, or another Counter instance.
517
518 >>> c = Counter('which')
519 >>> c.update('witch') # add elements from another iterable
520 >>> d = Counter('watch')
521 >>> c.update(d) # add elements from another counter
522 >>> c['h'] # four 'h' in which, witch, and watch
523 4
524
525 '''
526 # The regular dict.update() operation makes no sense here because the
527 # replace behavior results in the some of original untouched counts
528 # being mixed-in with all of the other counts for a mismash that
529 # doesn't have a straight-forward interpretation in most counting
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000530 # contexts. Instead, we implement straight-addition. Both the inputs
531 # and outputs are allowed to contain zero and negative counts.
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000532
533 if iterable is not None:
534 if isinstance(iterable, Mapping):
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000535 if self:
Raymond Hettingerf9092022009-06-29 18:30:43 +0000536 self_get = self.get
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000537 for elem, count in iterable.items():
Raymond Hettingerf9092022009-06-29 18:30:43 +0000538 self[elem] = count + self_get(elem, 0)
Raymond Hettingerdd01f8f2009-01-22 09:09:55 +0000539 else:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000540 super().update(iterable) # fast path when counter is empty
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000541 else:
Raymond Hettinger96f34102010-12-15 16:30:37 +0000542 _count_elements(self, iterable)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000543 if kwds:
544 self.update(kwds)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000545
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000546 def subtract(self, iterable=None, **kwds):
547 '''Like dict.update() but subtracts counts instead of replacing them.
548 Counts can be reduced below zero. Both the inputs and outputs are
549 allowed to contain zero and negative counts.
550
551 Source can be an iterable, a dictionary, or another Counter instance.
552
553 >>> c = Counter('which')
554 >>> c.subtract('witch') # subtract elements from another iterable
555 >>> c.subtract(Counter('watch')) # subtract elements from another counter
556 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
557 0
558 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
559 -1
560
561 '''
562 if iterable is not None:
Raymond Hettingerfc3c9cd2010-04-11 20:41:56 +0000563 self_get = self.get
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000564 if isinstance(iterable, Mapping):
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000565 for elem, count in iterable.items():
566 self[elem] = self_get(elem, 0) - count
567 else:
Raymond Hettinger9c01e442010-04-03 10:32:58 +0000568 for elem in iterable:
569 self[elem] = self_get(elem, 0) - 1
570 if kwds:
571 self.subtract(kwds)
572
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000573 def copy(self):
Raymond Hettinger1c746c22011-04-15 13:16:46 -0700574 'Return a shallow copy.'
575 return self.__class__(self)
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000576
Raymond Hettingerff728162011-01-03 02:44:14 +0000577 def __reduce__(self):
578 return self.__class__, (dict(self),)
579
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000580 def __delitem__(self, elem):
581 'Like dict.__delitem__() but does not raise KeyError for missing values.'
582 if elem in self:
Raymond Hettinger00d43fd2011-01-02 08:03:33 +0000583 super().__delitem__(elem)
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000584
Raymond Hettingerb8baf632009-01-14 02:20:07 +0000585 def __repr__(self):
586 if not self:
587 return '%s()' % self.__class__.__name__
588 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
589 return '%s({%s})' % (self.__class__.__name__, items)
590
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000591 # Multiset-style mathematical operations discussed in:
592 # Knuth TAOCP Volume II section 4.6.3 exercise 19
593 # and at http://en.wikipedia.org/wiki/Multiset
594 #
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000595 # Outputs guaranteed to only include positive counts.
596 #
597 # To strip negative and zero counts, add-in an empty counter:
598 # c += Counter()
599
600 def __add__(self, other):
601 '''Add counts from two counters.
602
603 >>> Counter('abbb') + Counter('bcc')
604 Counter({'b': 4, 'c': 2, 'a': 1})
605
606 '''
607 if not isinstance(other, Counter):
608 return NotImplemented
609 result = Counter()
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700610 for elem, count in self.items():
611 newcount = count + other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000612 if newcount > 0:
613 result[elem] = newcount
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700614 for elem, count in other.items():
615 if elem not in self and count > 0:
616 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000617 return result
618
619 def __sub__(self, other):
620 ''' Subtract count, but keep only results with positive counts.
621
622 >>> Counter('abbbc') - Counter('bccd')
623 Counter({'b': 2, 'a': 1})
624
625 '''
626 if not isinstance(other, Counter):
627 return NotImplemented
628 result = Counter()
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700629 for elem, count in self.items():
630 newcount = count - other[elem]
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000631 if newcount > 0:
632 result[elem] = newcount
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700633 for elem, count in other.items():
634 if elem not in self and count < 0:
635 result[elem] = 0 - count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000636 return result
637
638 def __or__(self, other):
639 '''Union is the maximum of value in either of the input counters.
640
641 >>> Counter('abbb') | Counter('bcc')
642 Counter({'b': 3, 'c': 2, 'a': 1})
643
644 '''
645 if not isinstance(other, Counter):
646 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000647 result = Counter()
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700648 for elem, count in self.items():
649 other_count = other[elem]
650 newcount = other_count if count < other_count else count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000651 if newcount > 0:
652 result[elem] = newcount
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700653 for elem, count in other.items():
654 if elem not in self and count > 0:
655 result[elem] = count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000656 return result
657
658 def __and__(self, other):
659 ''' Intersection is the minimum of corresponding counts.
660
661 >>> Counter('abbb') & Counter('bcc')
662 Counter({'b': 1})
663
664 '''
665 if not isinstance(other, Counter):
666 return NotImplemented
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000667 result = Counter()
Raymond Hettinger90375bc2011-04-17 19:49:29 -0700668 for elem, count in self.items():
669 other_count = other[elem]
670 newcount = count if count < other_count else other_count
Raymond Hettinger4d2073a2009-01-20 03:41:22 +0000671 if newcount > 0:
672 result[elem] = newcount
673 return result
674
Guido van Rossumd8faa362007-04-27 19:54:29 +0000675
Raymond Hettingerddb52402011-02-21 19:42:11 +0000676########################################################################
Raymond Hettingerc9423102011-02-22 01:55:36 +0000677### ChainMap (helper for configparser and string.Template)
Raymond Hettingerddb52402011-02-21 19:42:11 +0000678########################################################################
679
Raymond Hettinger9fe1ccf2011-02-26 01:02:51 +0000680class ChainMap(MutableMapping):
Raymond Hettingerddb52402011-02-21 19:42:11 +0000681 ''' A ChainMap groups multiple dicts (or other mappings) together
682 to create a single, updateable view.
683
684 The underlying mappings are stored in a list. That list is public and can
685 accessed or updated using the *maps* attribute. There is no other state.
686
687 Lookups search the underlying mappings successively until a key is found.
688 In contrast, writes, updates, and deletions only operate on the first
689 mapping.
690
691 '''
692
693 def __init__(self, *maps):
694 '''Initialize a ChainMap by setting *maps* to the given mappings.
695 If no mappings are provided, a single empty dictionary is used.
696
697 '''
698 self.maps = list(maps) or [{}] # always at least one map
699
700 def __missing__(self, key):
701 raise KeyError(key)
702
703 def __getitem__(self, key):
704 for mapping in self.maps:
705 try:
706 return mapping[key] # can't use 'key in mapping' with defaultdict
707 except KeyError:
708 pass
709 return self.__missing__(key) # support subclasses that define __missing__
710
711 def get(self, key, default=None):
712 return self[key] if key in self else default
713
714 def __len__(self):
715 return len(set().union(*self.maps)) # reuses stored hash values if possible
716
717 def __iter__(self):
718 return iter(set().union(*self.maps))
719
720 def __contains__(self, key):
721 return any(key in m for m in self.maps)
722
Raymond Hettingerd0321312011-02-26 06:53:58 +0000723 def __bool__(self):
724 return any(self.maps)
725
Raymond Hettingerddb52402011-02-21 19:42:11 +0000726 @_recursive_repr()
727 def __repr__(self):
728 return '{0.__class__.__name__}({1})'.format(
729 self, ', '.join(map(repr, self.maps)))
730
731 @classmethod
732 def fromkeys(cls, iterable, *args):
733 'Create a ChainMap with a single dict created from the iterable.'
734 return cls(dict.fromkeys(iterable, *args))
735
736 def copy(self):
737 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
738 return self.__class__(self.maps[0].copy(), *self.maps[1:])
739
740 __copy__ = copy
741
Raymond Hettinger499e1932011-02-23 07:56:53 +0000742 def new_child(self): # like Django's Context.push()
743 'New ChainMap with a new dict followed by all previous maps.'
744 return self.__class__({}, *self.maps)
745
746 @property
747 def parents(self): # like Django's Context.pop()
748 'New ChainMap from maps[1:].'
749 return self.__class__(*self.maps[1:])
750
Raymond Hettingerddb52402011-02-21 19:42:11 +0000751 def __setitem__(self, key, value):
752 self.maps[0][key] = value
753
754 def __delitem__(self, key):
755 try:
756 del self.maps[0][key]
757 except KeyError:
758 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
759
760 def popitem(self):
761 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
762 try:
763 return self.maps[0].popitem()
764 except KeyError:
765 raise KeyError('No keys found in the first mapping.')
766
767 def pop(self, key, *args):
768 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
769 try:
770 return self.maps[0].pop(key, *args)
771 except KeyError:
772 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
773
774 def clear(self):
775 'Clear maps[0], leaving maps[1:] intact.'
776 self.maps[0].clear()
777
778
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000779################################################################################
780### UserDict
781################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +0000782
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000783class UserDict(MutableMapping):
784
785 # Start by filling-out the abstract methods
786 def __init__(self, dict=None, **kwargs):
787 self.data = {}
788 if dict is not None:
789 self.update(dict)
790 if len(kwargs):
791 self.update(kwargs)
792 def __len__(self): return len(self.data)
793 def __getitem__(self, key):
794 if key in self.data:
795 return self.data[key]
796 if hasattr(self.__class__, "__missing__"):
797 return self.__class__.__missing__(self, key)
798 raise KeyError(key)
799 def __setitem__(self, key, item): self.data[key] = item
800 def __delitem__(self, key): del self.data[key]
801 def __iter__(self):
802 return iter(self.data)
803
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000804 # Modify __contains__ to work correctly when __missing__ is present
805 def __contains__(self, key):
806 return key in self.data
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000807
808 # Now, add the methods in dicts but not in MutableMapping
809 def __repr__(self): return repr(self.data)
810 def copy(self):
811 if self.__class__ is UserDict:
812 return UserDict(self.data.copy())
813 import copy
814 data = self.data
815 try:
816 self.data = {}
817 c = copy.copy(self)
818 finally:
819 self.data = data
820 c.update(self)
821 return c
822 @classmethod
823 def fromkeys(cls, iterable, value=None):
824 d = cls()
825 for key in iterable:
826 d[key] = value
827 return d
828
Raymond Hettinger48b8b662008-02-05 01:53:00 +0000829
830
831################################################################################
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000832### UserList
833################################################################################
834
835class UserList(MutableSequence):
836 """A more or less complete user-defined wrapper around list objects."""
837 def __init__(self, initlist=None):
838 self.data = []
839 if initlist is not None:
840 # XXX should this accept an arbitrary sequence?
841 if type(initlist) == type(self.data):
842 self.data[:] = initlist
843 elif isinstance(initlist, UserList):
844 self.data[:] = initlist.data[:]
845 else:
846 self.data = list(initlist)
847 def __repr__(self): return repr(self.data)
848 def __lt__(self, other): return self.data < self.__cast(other)
849 def __le__(self, other): return self.data <= self.__cast(other)
850 def __eq__(self, other): return self.data == self.__cast(other)
851 def __ne__(self, other): return self.data != self.__cast(other)
852 def __gt__(self, other): return self.data > self.__cast(other)
853 def __ge__(self, other): return self.data >= self.__cast(other)
854 def __cast(self, other):
855 return other.data if isinstance(other, UserList) else other
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000856 def __contains__(self, item): return item in self.data
857 def __len__(self): return len(self.data)
858 def __getitem__(self, i): return self.data[i]
859 def __setitem__(self, i, item): self.data[i] = item
860 def __delitem__(self, i): del self.data[i]
861 def __add__(self, other):
862 if isinstance(other, UserList):
863 return self.__class__(self.data + other.data)
864 elif isinstance(other, type(self.data)):
865 return self.__class__(self.data + other)
866 return self.__class__(self.data + list(other))
867 def __radd__(self, other):
868 if isinstance(other, UserList):
869 return self.__class__(other.data + self.data)
870 elif isinstance(other, type(self.data)):
871 return self.__class__(other + self.data)
872 return self.__class__(list(other) + self.data)
873 def __iadd__(self, other):
874 if isinstance(other, UserList):
875 self.data += other.data
876 elif isinstance(other, type(self.data)):
877 self.data += other
878 else:
879 self.data += list(other)
880 return self
881 def __mul__(self, n):
882 return self.__class__(self.data*n)
883 __rmul__ = __mul__
884 def __imul__(self, n):
885 self.data *= n
886 return self
887 def append(self, item): self.data.append(item)
888 def insert(self, i, item): self.data.insert(i, item)
889 def pop(self, i=-1): return self.data.pop(i)
890 def remove(self, item): self.data.remove(item)
Eli Benderskycbbaa962011-02-25 05:47:53 +0000891 def clear(self): self.data.clear()
Raymond Hettinger1c7b7f72011-05-05 14:34:35 -0700892 def copy(self): return self.__class__(self)
Raymond Hettinger53dbe392008-02-12 20:03:09 +0000893 def count(self, item): return self.data.count(item)
894 def index(self, item, *args): return self.data.index(item, *args)
895 def reverse(self): self.data.reverse()
896 def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
897 def extend(self, other):
898 if isinstance(other, UserList):
899 self.data.extend(other.data)
900 else:
901 self.data.extend(other)
902
903
904
905################################################################################
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000906### UserString
907################################################################################
908
909class UserString(Sequence):
910 def __init__(self, seq):
911 if isinstance(seq, str):
912 self.data = seq
913 elif isinstance(seq, UserString):
914 self.data = seq.data[:]
915 else:
916 self.data = str(seq)
917 def __str__(self): return str(self.data)
918 def __repr__(self): return repr(self.data)
919 def __int__(self): return int(self.data)
Raymond Hettingerb3a65f82008-02-21 22:11:37 +0000920 def __float__(self): return float(self.data)
921 def __complex__(self): return complex(self.data)
922 def __hash__(self): return hash(self.data)
923
924 def __eq__(self, string):
925 if isinstance(string, UserString):
926 return self.data == string.data
927 return self.data == string
928 def __ne__(self, string):
929 if isinstance(string, UserString):
930 return self.data != string.data
931 return self.data != string
932 def __lt__(self, string):
933 if isinstance(string, UserString):
934 return self.data < string.data
935 return self.data < string
936 def __le__(self, string):
937 if isinstance(string, UserString):
938 return self.data <= string.data
939 return self.data <= string
940 def __gt__(self, string):
941 if isinstance(string, UserString):
942 return self.data > string.data
943 return self.data > string
944 def __ge__(self, string):
945 if isinstance(string, UserString):
946 return self.data >= string.data
947 return self.data >= string
948
949 def __contains__(self, char):
950 if isinstance(char, UserString):
951 char = char.data
952 return char in self.data
953
954 def __len__(self): return len(self.data)
955 def __getitem__(self, index): return self.__class__(self.data[index])
956 def __add__(self, other):
957 if isinstance(other, UserString):
958 return self.__class__(self.data + other.data)
959 elif isinstance(other, str):
960 return self.__class__(self.data + other)
961 return self.__class__(self.data + str(other))
962 def __radd__(self, other):
963 if isinstance(other, str):
964 return self.__class__(other + self.data)
965 return self.__class__(str(other) + self.data)
966 def __mul__(self, n):
967 return self.__class__(self.data*n)
968 __rmul__ = __mul__
969 def __mod__(self, args):
970 return self.__class__(self.data % args)
971
972 # the following methods are defined in alphabetical order:
973 def capitalize(self): return self.__class__(self.data.capitalize())
974 def center(self, width, *args):
975 return self.__class__(self.data.center(width, *args))
976 def count(self, sub, start=0, end=_sys.maxsize):
977 if isinstance(sub, UserString):
978 sub = sub.data
979 return self.data.count(sub, start, end)
980 def encode(self, encoding=None, errors=None): # XXX improve this?
981 if encoding:
982 if errors:
983 return self.__class__(self.data.encode(encoding, errors))
984 return self.__class__(self.data.encode(encoding))
985 return self.__class__(self.data.encode())
986 def endswith(self, suffix, start=0, end=_sys.maxsize):
987 return self.data.endswith(suffix, start, end)
988 def expandtabs(self, tabsize=8):
989 return self.__class__(self.data.expandtabs(tabsize))
990 def find(self, sub, start=0, end=_sys.maxsize):
991 if isinstance(sub, UserString):
992 sub = sub.data
993 return self.data.find(sub, start, end)
994 def format(self, *args, **kwds):
995 return self.data.format(*args, **kwds)
996 def index(self, sub, start=0, end=_sys.maxsize):
997 return self.data.index(sub, start, end)
998 def isalpha(self): return self.data.isalpha()
999 def isalnum(self): return self.data.isalnum()
1000 def isdecimal(self): return self.data.isdecimal()
1001 def isdigit(self): return self.data.isdigit()
1002 def isidentifier(self): return self.data.isidentifier()
1003 def islower(self): return self.data.islower()
1004 def isnumeric(self): return self.data.isnumeric()
1005 def isspace(self): return self.data.isspace()
1006 def istitle(self): return self.data.istitle()
1007 def isupper(self): return self.data.isupper()
1008 def join(self, seq): return self.data.join(seq)
1009 def ljust(self, width, *args):
1010 return self.__class__(self.data.ljust(width, *args))
1011 def lower(self): return self.__class__(self.data.lower())
1012 def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1013 def partition(self, sep):
1014 return self.data.partition(sep)
1015 def replace(self, old, new, maxsplit=-1):
1016 if isinstance(old, UserString):
1017 old = old.data
1018 if isinstance(new, UserString):
1019 new = new.data
1020 return self.__class__(self.data.replace(old, new, maxsplit))
1021 def rfind(self, sub, start=0, end=_sys.maxsize):
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +00001022 if isinstance(sub, UserString):
1023 sub = sub.data
Raymond Hettingerb3a65f82008-02-21 22:11:37 +00001024 return self.data.rfind(sub, start, end)
1025 def rindex(self, sub, start=0, end=_sys.maxsize):
1026 return self.data.rindex(sub, start, end)
1027 def rjust(self, width, *args):
1028 return self.__class__(self.data.rjust(width, *args))
1029 def rpartition(self, sep):
1030 return self.data.rpartition(sep)
1031 def rstrip(self, chars=None):
1032 return self.__class__(self.data.rstrip(chars))
1033 def split(self, sep=None, maxsplit=-1):
1034 return self.data.split(sep, maxsplit)
1035 def rsplit(self, sep=None, maxsplit=-1):
1036 return self.data.rsplit(sep, maxsplit)
1037 def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1038 def startswith(self, prefix, start=0, end=_sys.maxsize):
1039 return self.data.startswith(prefix, start, end)
1040 def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1041 def swapcase(self): return self.__class__(self.data.swapcase())
1042 def title(self): return self.__class__(self.data.title())
1043 def translate(self, *args):
1044 return self.__class__(self.data.translate(*args))
1045 def upper(self): return self.__class__(self.data.upper())
1046 def zfill(self, width): return self.__class__(self.data.zfill(width))
1047
1048
1049
1050################################################################################
Raymond Hettinger48b8b662008-02-05 01:53:00 +00001051### Simple tests
1052################################################################################
Guido van Rossumd8faa362007-04-27 19:54:29 +00001053
1054if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001055 # verify that instances can be pickled
Guido van Rossum99603b02007-07-20 00:22:32 +00001056 from pickle import loads, dumps
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001057 Point = namedtuple('Point', 'x, y', True)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001058 p = Point(x=10, y=20)
1059 assert p == loads(dumps(p))
1060
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001061 # test and demonstrate ability to override methods
Christian Heimes043d6f62008-01-07 17:19:16 +00001062 class Point(namedtuple('Point', 'x y')):
Christian Heimes25bb7832008-01-11 16:17:00 +00001063 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001064 @property
1065 def hypot(self):
1066 return (self.x ** 2 + self.y ** 2) ** 0.5
Christian Heimes790c8232008-01-07 21:14:23 +00001067 def __str__(self):
Christian Heimes25bb7832008-01-11 16:17:00 +00001068 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
Christian Heimes043d6f62008-01-07 17:19:16 +00001069
Christian Heimes25bb7832008-01-11 16:17:00 +00001070 for p in Point(3, 4), Point(14, 5/7.):
Christian Heimes790c8232008-01-07 21:14:23 +00001071 print (p)
Christian Heimes043d6f62008-01-07 17:19:16 +00001072
1073 class Point(namedtuple('Point', 'x y')):
1074 'Point class with optimized _make() and _replace() without error-checking'
Christian Heimes25bb7832008-01-11 16:17:00 +00001075 __slots__ = ()
Christian Heimes043d6f62008-01-07 17:19:16 +00001076 _make = classmethod(tuple.__new__)
1077 def _replace(self, _map=map, **kwds):
Christian Heimes2380ac72008-01-09 00:17:24 +00001078 return self._make(_map(kwds.get, ('x', 'y'), self))
Christian Heimes043d6f62008-01-07 17:19:16 +00001079
1080 print(Point(11, 22)._replace(x=100))
Guido van Rossum3d392eb2007-11-16 00:35:22 +00001081
Christian Heimes25bb7832008-01-11 16:17:00 +00001082 Point3D = namedtuple('Point3D', Point._fields + ('z',))
1083 print(Point3D.__doc__)
1084
Guido van Rossumd8faa362007-04-27 19:54:29 +00001085 import doctest
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001086 TestResults = namedtuple('TestResults', 'failed attempted')
Guido van Rossumd8faa362007-04-27 19:54:29 +00001087 print(TestResults(*doctest.testmod()))