lmgsanm

每天学习一点,每天进步一点点…… Tomorrow is another beatifull day

导航

python模块:collections

   1 '''This module implements specialized container datatypes providing
   2 alternatives to Python's general purpose built-in containers, dict,
   3 list, set, and tuple.
   4 
   5 * namedtuple   factory function for creating tuple subclasses with named fields
   6 * deque        list-like container with fast appends and pops on either end
   7 * ChainMap     dict-like class for creating a single view of multiple mappings
   8 * Counter      dict subclass for counting hashable objects
   9 * OrderedDict  dict subclass that remembers the order entries were added
  10 * defaultdict  dict subclass that calls a factory function to supply missing values
  11 * UserDict     wrapper around dictionary objects for easier dict subclassing
  12 * UserList     wrapper around list objects for easier list subclassing
  13 * UserString   wrapper around string objects for easier string subclassing
  14 
  15 '''
  16 
  17 __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
  18             'UserString', 'Counter', 'OrderedDict', 'ChainMap']
  19 
  20 # For backwards compatibility, continue to make the collections ABCs
  21 # available through the collections module.
  22 from _collections_abc import *
  23 import _collections_abc
  24 __all__ += _collections_abc.__all__
  25 
  26 from operator import itemgetter as _itemgetter, eq as _eq
  27 from keyword import iskeyword as _iskeyword
  28 import sys as _sys
  29 import heapq as _heapq
  30 from _weakref import proxy as _proxy
  31 from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
  32 from reprlib import recursive_repr as _recursive_repr
  33 
  34 try:
  35     from _collections import deque
  36 except ImportError:
  37     pass
  38 else:
  39     MutableSequence.register(deque)
  40 
  41 try:
  42     from _collections import defaultdict
  43 except ImportError:
  44     pass
  45 
  46 
  47 ################################################################################
  48 ### OrderedDict
  49 ################################################################################
  50 
  51 class _OrderedDictKeysView(KeysView):
  52 
  53     def __reversed__(self):
  54         yield from reversed(self._mapping)
  55 
  56 class _OrderedDictItemsView(ItemsView):
  57 
  58     def __reversed__(self):
  59         for key in reversed(self._mapping):
  60             yield (key, self._mapping[key])
  61 
  62 class _OrderedDictValuesView(ValuesView):
  63 
  64     def __reversed__(self):
  65         for key in reversed(self._mapping):
  66             yield self._mapping[key]
  67 
  68 class _Link(object):
  69     __slots__ = 'prev', 'next', 'key', '__weakref__'
  70 
  71 class OrderedDict(dict):
  72     'Dictionary that remembers insertion order'
  73     # An inherited dict maps keys to values.
  74     # The inherited dict provides __getitem__, __len__, __contains__, and get.
  75     # The remaining methods are order-aware.
  76     # Big-O running times for all methods are the same as regular dictionaries.
  77 
  78     # The internal self.__map dict maps keys to links in a doubly linked list.
  79     # The circular doubly linked list starts and ends with a sentinel element.
  80     # The sentinel element never gets deleted (this simplifies the algorithm).
  81     # The sentinel is in self.__hardroot with a weakref proxy in self.__root.
  82     # The prev links are weakref proxies (to prevent circular references).
  83     # Individual links are kept alive by the hard reference in self.__map.
  84     # Those hard references disappear when a key is deleted from an OrderedDict.
  85 
  86     def __init__(*args, **kwds):
  87         '''Initialize an ordered dictionary.  The signature is the same as
  88         regular dictionaries.  Keyword argument order is preserved.
  89         '''
  90         if not args:
  91             raise TypeError("descriptor '__init__' of 'OrderedDict' object "
  92                             "needs an argument")
  93         self, *args = args
  94         if len(args) > 1:
  95             raise TypeError('expected at most 1 arguments, got %d' % len(args))
  96         try:
  97             self.__root
  98         except AttributeError:
  99             self.__hardroot = _Link()
 100             self.__root = root = _proxy(self.__hardroot)
 101             root.prev = root.next = root
 102             self.__map = {}
 103         self.__update(*args, **kwds)
 104 
 105     def __setitem__(self, key, value,
 106                     dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
 107         'od.__setitem__(i, y) <==> od[i]=y'
 108         # Setting a new item creates a new link at the end of the linked list,
 109         # and the inherited dictionary is updated with the new key/value pair.
 110         if key not in self:
 111             self.__map[key] = link = Link()
 112             root = self.__root
 113             last = root.prev
 114             link.prev, link.next, link.key = last, root, key
 115             last.next = link
 116             root.prev = proxy(link)
 117         dict_setitem(self, key, value)
 118 
 119     def __delitem__(self, key, dict_delitem=dict.__delitem__):
 120         'od.__delitem__(y) <==> del od[y]'
 121         # Deleting an existing item uses self.__map to find the link which gets
 122         # removed by updating the links in the predecessor and successor nodes.
 123         dict_delitem(self, key)
 124         link = self.__map.pop(key)
 125         link_prev = link.prev
 126         link_next = link.next
 127         link_prev.next = link_next
 128         link_next.prev = link_prev
 129         link.prev = None
 130         link.next = None
 131 
 132     def __iter__(self):
 133         'od.__iter__() <==> iter(od)'
 134         # Traverse the linked list in order.
 135         root = self.__root
 136         curr = root.next
 137         while curr is not root:
 138             yield curr.key
 139             curr = curr.next
 140 
 141     def __reversed__(self):
 142         'od.__reversed__() <==> reversed(od)'
 143         # Traverse the linked list in reverse order.
 144         root = self.__root
 145         curr = root.prev
 146         while curr is not root:
 147             yield curr.key
 148             curr = curr.prev
 149 
 150     def clear(self):
 151         'od.clear() -> None.  Remove all items from od.'
 152         root = self.__root
 153         root.prev = root.next = root
 154         self.__map.clear()
 155         dict.clear(self)
 156 
 157     def popitem(self, last=True):
 158         '''Remove and return a (key, value) pair from the dictionary.
 159 
 160         Pairs are returned in LIFO order if last is true or FIFO order if false.
 161         '''
 162         if not self:
 163             raise KeyError('dictionary is empty')
 164         root = self.__root
 165         if last:
 166             link = root.prev
 167             link_prev = link.prev
 168             link_prev.next = root
 169             root.prev = link_prev
 170         else:
 171             link = root.next
 172             link_next = link.next
 173             root.next = link_next
 174             link_next.prev = root
 175         key = link.key
 176         del self.__map[key]
 177         value = dict.pop(self, key)
 178         return key, value
 179 
 180     def move_to_end(self, key, last=True):
 181         '''Move an existing element to the end (or beginning if last==False).
 182 
 183         Raises KeyError if the element does not exist.
 184         When last=True, acts like a fast version of self[key]=self.pop(key).
 185 
 186         '''
 187         link = self.__map[key]
 188         link_prev = link.prev
 189         link_next = link.next
 190         soft_link = link_next.prev
 191         link_prev.next = link_next
 192         link_next.prev = link_prev
 193         root = self.__root
 194         if last:
 195             last = root.prev
 196             link.prev = last
 197             link.next = root
 198             root.prev = soft_link
 199             last.next = link
 200         else:
 201             first = root.next
 202             link.prev = root
 203             link.next = first
 204             first.prev = soft_link
 205             root.next = link
 206 
 207     def __sizeof__(self):
 208         sizeof = _sys.getsizeof
 209         n = len(self) + 1                       # number of links including root
 210         size = sizeof(self.__dict__)            # instance dictionary
 211         size += sizeof(self.__map) * 2          # internal dict and inherited dict
 212         size += sizeof(self.__hardroot) * n     # link objects
 213         size += sizeof(self.__root) * n         # proxy objects
 214         return size
 215 
 216     update = __update = MutableMapping.update
 217 
 218     def keys(self):
 219         "D.keys() -> a set-like object providing a view on D's keys"
 220         return _OrderedDictKeysView(self)
 221 
 222     def items(self):
 223         "D.items() -> a set-like object providing a view on D's items"
 224         return _OrderedDictItemsView(self)
 225 
 226     def values(self):
 227         "D.values() -> an object providing a view on D's values"
 228         return _OrderedDictValuesView(self)
 229 
 230     __ne__ = MutableMapping.__ne__
 231 
 232     __marker = object()
 233 
 234     def pop(self, key, default=__marker):
 235         '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
 236         value.  If key is not found, d is returned if given, otherwise KeyError
 237         is raised.
 238 
 239         '''
 240         if key in self:
 241             result = self[key]
 242             del self[key]
 243             return result
 244         if default is self.__marker:
 245             raise KeyError(key)
 246         return default
 247 
 248     def setdefault(self, key, default=None):
 249         'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
 250         if key in self:
 251             return self[key]
 252         self[key] = default
 253         return default
 254 
 255     @_recursive_repr()
 256     def __repr__(self):
 257         'od.__repr__() <==> repr(od)'
 258         if not self:
 259             return '%s()' % (self.__class__.__name__,)
 260         return '%s(%r)' % (self.__class__.__name__, list(self.items()))
 261 
 262     def __reduce__(self):
 263         'Return state information for pickling'
 264         inst_dict = vars(self).copy()
 265         for k in vars(OrderedDict()):
 266             inst_dict.pop(k, None)
 267         return self.__class__, (), inst_dict or None, None, iter(self.items())
 268 
 269     def copy(self):
 270         'od.copy() -> a shallow copy of od'
 271         return self.__class__(self)
 272 
 273     @classmethod
 274     def fromkeys(cls, iterable, value=None):
 275         '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
 276         If not specified, the value defaults to None.
 277 
 278         '''
 279         self = cls()
 280         for key in iterable:
 281             self[key] = value
 282         return self
 283 
 284     def __eq__(self, other):
 285         '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
 286         while comparison to a regular mapping is order-insensitive.
 287 
 288         '''
 289         if isinstance(other, OrderedDict):
 290             return dict.__eq__(self, other) and all(map(_eq, self, other))
 291         return dict.__eq__(self, other)
 292 
 293 
 294 try:
 295     from _collections import OrderedDict
 296 except ImportError:
 297     # Leave the pure Python version in place.
 298     pass
 299 
 300 
 301 ################################################################################
 302 ### namedtuple
 303 ################################################################################
 304 
 305 _class_template = """\
 306 from builtins import property as _property, tuple as _tuple
 307 from operator import itemgetter as _itemgetter
 308 from collections import OrderedDict
 309 
 310 class {typename}(tuple):
 311     '{typename}({arg_list})'
 312 
 313     __slots__ = ()
 314 
 315     _fields = {field_names!r}
 316 
 317     def __new__(_cls, {arg_list}):
 318         'Create new instance of {typename}({arg_list})'
 319         return _tuple.__new__(_cls, ({arg_list}))
 320 
 321     @classmethod
 322     def _make(cls, iterable, new=tuple.__new__, len=len):
 323         'Make a new {typename} object from a sequence or iterable'
 324         result = new(cls, iterable)
 325         if len(result) != {num_fields:d}:
 326             raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result))
 327         return result
 328 
 329     def _replace(_self, **kwds):
 330         'Return a new {typename} object replacing specified fields with new values'
 331         result = _self._make(map(kwds.pop, {field_names!r}, _self))
 332         if kwds:
 333             raise ValueError('Got unexpected field names: %r' % list(kwds))
 334         return result
 335 
 336     def __repr__(self):
 337         'Return a nicely formatted representation string'
 338         return self.__class__.__name__ + '({repr_fmt})' % self
 339 
 340     def _asdict(self):
 341         'Return a new OrderedDict which maps field names to their values.'
 342         return OrderedDict(zip(self._fields, self))
 343 
 344     def __getnewargs__(self):
 345         'Return self as a plain tuple.  Used by copy and pickle.'
 346         return tuple(self)
 347 
 348 {field_defs}
 349 """
 350 
 351 _repr_template = '{name}=%r'
 352 
 353 _field_template = '''\
 354     {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
 355 '''
 356 
 357 def namedtuple(typename, field_names, *, verbose=False, rename=False, module=None):
 358     """Returns a new subclass of tuple with named fields.
 359 
 360     >>> Point = namedtuple('Point', ['x', 'y'])
 361     >>> Point.__doc__                   # docstring for the new class
 362     'Point(x, y)'
 363     >>> p = Point(11, y=22)             # instantiate with positional args or keywords
 364     >>> p[0] + p[1]                     # indexable like a plain tuple
 365     33
 366     >>> x, y = p                        # unpack like a regular tuple
 367     >>> x, y
 368     (11, 22)
 369     >>> p.x + p.y                       # fields also accessible by name
 370     33
 371     >>> d = p._asdict()                 # convert to a dictionary
 372     >>> d['x']
 373     11
 374     >>> Point(**d)                      # convert from a dictionary
 375     Point(x=11, y=22)
 376     >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
 377     Point(x=100, y=22)
 378 
 379     """
 380 
 381     # Validate the field names.  At the user's option, either generate an error
 382     # message or automatically replace the field name with a valid name.
 383     if isinstance(field_names, str):
 384         field_names = field_names.replace(',', ' ').split()
 385     field_names = list(map(str, field_names))
 386     typename = str(typename)
 387     if rename:
 388         seen = set()
 389         for index, name in enumerate(field_names):
 390             if (not name.isidentifier()
 391                 or _iskeyword(name)
 392                 or name.startswith('_')
 393                 or name in seen):
 394                 field_names[index] = '_%d' % index
 395             seen.add(name)
 396     for name in [typename] + field_names:
 397         if type(name) is not str:
 398             raise TypeError('Type names and field names must be strings')
 399         if not name.isidentifier():
 400             raise ValueError('Type names and field names must be valid '
 401                              'identifiers: %r' % name)
 402         if _iskeyword(name):
 403             raise ValueError('Type names and field names cannot be a '
 404                              'keyword: %r' % name)
 405     seen = set()
 406     for name in field_names:
 407         if name.startswith('_') and not rename:
 408             raise ValueError('Field names cannot start with an underscore: '
 409                              '%r' % name)
 410         if name in seen:
 411             raise ValueError('Encountered duplicate field name: %r' % name)
 412         seen.add(name)
 413 
 414     # Fill-in the class template
 415     class_definition = _class_template.format(
 416         typename = typename,
 417         field_names = tuple(field_names),
 418         num_fields = len(field_names),
 419         arg_list = repr(tuple(field_names)).replace("'", "")[1:-1],
 420         repr_fmt = ', '.join(_repr_template.format(name=name)
 421                              for name in field_names),
 422         field_defs = '\n'.join(_field_template.format(index=index, name=name)
 423                                for index, name in enumerate(field_names))
 424     )
 425 
 426     # Execute the template string in a temporary namespace and support
 427     # tracing utilities by setting a value for frame.f_globals['__name__']
 428     namespace = dict(__name__='namedtuple_%s' % typename)
 429     exec(class_definition, namespace)
 430     result = namespace[typename]
 431     result._source = class_definition
 432     if verbose:
 433         print(result._source)
 434 
 435     # For pickling to work, the __module__ variable needs to be set to the frame
 436     # where the named tuple is created.  Bypass this step in environments where
 437     # sys._getframe is not defined (Jython for example) or sys._getframe is not
 438     # defined for arguments greater than 0 (IronPython), or where the user has
 439     # specified a particular module.
 440     if module is None:
 441         try:
 442             module = _sys._getframe(1).f_globals.get('__name__', '__main__')
 443         except (AttributeError, ValueError):
 444             pass
 445     if module is not None:
 446         result.__module__ = module
 447 
 448     return result
 449 
 450 
 451 ########################################################################
 452 ###  Counter
 453 ########################################################################
 454 
 455 def _count_elements(mapping, iterable):
 456     'Tally elements from the iterable.'
 457     mapping_get = mapping.get
 458     for elem in iterable:
 459         mapping[elem] = mapping_get(elem, 0) + 1
 460 
 461 try:                                    # Load C helper function if available
 462     from _collections import _count_elements
 463 except ImportError:
 464     pass
 465 
 466 class Counter(dict):
 467     '''Dict subclass for counting hashable items.  Sometimes called a bag
 468     or multiset.  Elements are stored as dictionary keys and their counts
 469     are stored as dictionary values.
 470 
 471     >>> c = Counter('abcdeabcdabcaba')  # count elements from a string
 472 
 473     >>> c.most_common(3)                # three most common elements
 474     [('a', 5), ('b', 4), ('c', 3)]
 475     >>> sorted(c)                       # list all unique elements
 476     ['a', 'b', 'c', 'd', 'e']
 477     >>> ''.join(sorted(c.elements()))   # list elements with repetitions
 478     'aaaaabbbbcccdde'
 479     >>> sum(c.values())                 # total of all counts
 480     15
 481 
 482     >>> c['a']                          # count of letter 'a'
 483     5
 484     >>> for elem in 'shazam':           # update counts from an iterable
 485     ...     c[elem] += 1                # by adding 1 to each element's count
 486     >>> c['a']                          # now there are seven 'a'
 487     7
 488     >>> del c['b']                      # remove all 'b'
 489     >>> c['b']                          # now there are zero 'b'
 490     0
 491 
 492     >>> d = Counter('simsalabim')       # make another counter
 493     >>> c.update(d)                     # add in the second counter
 494     >>> c['a']                          # now there are nine 'a'
 495     9
 496 
 497     >>> c.clear()                       # empty the counter
 498     >>> c
 499     Counter()
 500 
 501     Note:  If a count is set to zero or reduced to zero, it will remain
 502     in the counter until the entry is deleted or the counter is cleared:
 503 
 504     >>> c = Counter('aaabbc')
 505     >>> c['b'] -= 2                     # reduce the count of 'b' by two
 506     >>> c.most_common()                 # 'b' is still in, but its count is zero
 507     [('a', 3), ('c', 1), ('b', 0)]
 508 
 509     '''
 510     # References:
 511     #   http://en.wikipedia.org/wiki/Multiset
 512     #   http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
 513     #   http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
 514     #   http://code.activestate.com/recipes/259174/
 515     #   Knuth, TAOCP Vol. II section 4.6.3
 516 
 517     def __init__(*args, **kwds):
 518         '''Create a new, empty Counter object.  And if given, count elements
 519         from an input iterable.  Or, initialize the count from another mapping
 520         of elements to their counts.
 521 
 522         >>> c = Counter()                           # a new, empty counter
 523         >>> c = Counter('gallahad')                 # a new counter from an iterable
 524         >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping
 525         >>> c = Counter(a=4, b=2)                   # a new counter from keyword args
 526 
 527         '''
 528         if not args:
 529             raise TypeError("descriptor '__init__' of 'Counter' object "
 530                             "needs an argument")
 531         self, *args = args
 532         if len(args) > 1:
 533             raise TypeError('expected at most 1 arguments, got %d' % len(args))
 534         super(Counter, self).__init__()
 535         self.update(*args, **kwds)
 536 
 537     def __missing__(self, key):
 538         'The count of elements not in the Counter is zero.'
 539         # Needed so that self[missing_item] does not raise KeyError
 540         return 0
 541 
 542     def most_common(self, n=None):
 543         '''List the n most common elements and their counts from the most
 544         common to the least.  If n is None, then list all element counts.
 545 
 546         >>> Counter('abcdeabcdabcaba').most_common(3)
 547         [('a', 5), ('b', 4), ('c', 3)]
 548 
 549         '''
 550         # Emulate Bag.sortedByCount from Smalltalk
 551         if n is None:
 552             return sorted(self.items(), key=_itemgetter(1), reverse=True)
 553         return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
 554 
 555     def elements(self):
 556         '''Iterator over elements repeating each as many times as its count.
 557 
 558         >>> c = Counter('ABCABC')
 559         >>> sorted(c.elements())
 560         ['A', 'A', 'B', 'B', 'C', 'C']
 561 
 562         # Knuth's example for prime factors of 1836:  2**2 * 3**3 * 17**1
 563         >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
 564         >>> product = 1
 565         >>> for factor in prime_factors.elements():     # loop over factors
 566         ...     product *= factor                       # and multiply them
 567         >>> product
 568         1836
 569 
 570         Note, if an element's count has been set to zero or is a negative
 571         number, elements() will ignore it.
 572 
 573         '''
 574         # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
 575         return _chain.from_iterable(_starmap(_repeat, self.items()))
 576 
 577     # Override dict methods where necessary
 578 
 579     @classmethod
 580     def fromkeys(cls, iterable, v=None):
 581         # There is no equivalent method for counters because setting v=1
 582         # means that no element can have a count greater than one.
 583         raise NotImplementedError(
 584             'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
 585 
 586     def update(*args, **kwds):
 587         '''Like dict.update() but add counts instead of replacing them.
 588 
 589         Source can be an iterable, a dictionary, or another Counter instance.
 590 
 591         >>> c = Counter('which')
 592         >>> c.update('witch')           # add elements from another iterable
 593         >>> d = Counter('watch')
 594         >>> c.update(d)                 # add elements from another counter
 595         >>> c['h']                      # four 'h' in which, witch, and watch
 596         4
 597 
 598         '''
 599         # The regular dict.update() operation makes no sense here because the
 600         # replace behavior results in the some of original untouched counts
 601         # being mixed-in with all of the other counts for a mismash that
 602         # doesn't have a straight-forward interpretation in most counting
 603         # contexts.  Instead, we implement straight-addition.  Both the inputs
 604         # and outputs are allowed to contain zero and negative counts.
 605 
 606         if not args:
 607             raise TypeError("descriptor 'update' of 'Counter' object "
 608                             "needs an argument")
 609         self, *args = args
 610         if len(args) > 1:
 611             raise TypeError('expected at most 1 arguments, got %d' % len(args))
 612         iterable = args[0] if args else None
 613         if iterable is not None:
 614             if isinstance(iterable, Mapping):
 615                 if self:
 616                     self_get = self.get
 617                     for elem, count in iterable.items():
 618                         self[elem] = count + self_get(elem, 0)
 619                 else:
 620                     super(Counter, self).update(iterable) # fast path when counter is empty
 621             else:
 622                 _count_elements(self, iterable)
 623         if kwds:
 624             self.update(kwds)
 625 
 626     def subtract(*args, **kwds):
 627         '''Like dict.update() but subtracts counts instead of replacing them.
 628         Counts can be reduced below zero.  Both the inputs and outputs are
 629         allowed to contain zero and negative counts.
 630 
 631         Source can be an iterable, a dictionary, or another Counter instance.
 632 
 633         >>> c = Counter('which')
 634         >>> c.subtract('witch')             # subtract elements from another iterable
 635         >>> c.subtract(Counter('watch'))    # subtract elements from another counter
 636         >>> c['h']                          # 2 in which, minus 1 in witch, minus 1 in watch
 637         0
 638         >>> c['w']                          # 1 in which, minus 1 in witch, minus 1 in watch
 639         -1
 640 
 641         '''
 642         if not args:
 643             raise TypeError("descriptor 'subtract' of 'Counter' object "
 644                             "needs an argument")
 645         self, *args = args
 646         if len(args) > 1:
 647             raise TypeError('expected at most 1 arguments, got %d' % len(args))
 648         iterable = args[0] if args else None
 649         if iterable is not None:
 650             self_get = self.get
 651             if isinstance(iterable, Mapping):
 652                 for elem, count in iterable.items():
 653                     self[elem] = self_get(elem, 0) - count
 654             else:
 655                 for elem in iterable:
 656                     self[elem] = self_get(elem, 0) - 1
 657         if kwds:
 658             self.subtract(kwds)
 659 
 660     def copy(self):
 661         'Return a shallow copy.'
 662         return self.__class__(self)
 663 
 664     def __reduce__(self):
 665         return self.__class__, (dict(self),)
 666 
 667     def __delitem__(self, elem):
 668         'Like dict.__delitem__() but does not raise KeyError for missing values.'
 669         if elem in self:
 670             super().__delitem__(elem)
 671 
 672     def __repr__(self):
 673         if not self:
 674             return '%s()' % self.__class__.__name__
 675         try:
 676             items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
 677             return '%s({%s})' % (self.__class__.__name__, items)
 678         except TypeError:
 679             # handle case where values are not orderable
 680             return '{0}({1!r})'.format(self.__class__.__name__, dict(self))
 681 
 682     # Multiset-style mathematical operations discussed in:
 683     #       Knuth TAOCP Volume II section 4.6.3 exercise 19
 684     #       and at http://en.wikipedia.org/wiki/Multiset
 685     #
 686     # Outputs guaranteed to only include positive counts.
 687     #
 688     # To strip negative and zero counts, add-in an empty counter:
 689     #       c += Counter()
 690 
 691     def __add__(self, other):
 692         '''Add counts from two counters.
 693 
 694         >>> Counter('abbb') + Counter('bcc')
 695         Counter({'b': 4, 'c': 2, 'a': 1})
 696 
 697         '''
 698         if not isinstance(other, Counter):
 699             return NotImplemented
 700         result = Counter()
 701         for elem, count in self.items():
 702             newcount = count + other[elem]
 703             if newcount > 0:
 704                 result[elem] = newcount
 705         for elem, count in other.items():
 706             if elem not in self and count > 0:
 707                 result[elem] = count
 708         return result
 709 
 710     def __sub__(self, other):
 711         ''' Subtract count, but keep only results with positive counts.
 712 
 713         >>> Counter('abbbc') - Counter('bccd')
 714         Counter({'b': 2, 'a': 1})
 715 
 716         '''
 717         if not isinstance(other, Counter):
 718             return NotImplemented
 719         result = Counter()
 720         for elem, count in self.items():
 721             newcount = count - other[elem]
 722             if newcount > 0:
 723                 result[elem] = newcount
 724         for elem, count in other.items():
 725             if elem not in self and count < 0:
 726                 result[elem] = 0 - count
 727         return result
 728 
 729     def __or__(self, other):
 730         '''Union is the maximum of value in either of the input counters.
 731 
 732         >>> Counter('abbb') | Counter('bcc')
 733         Counter({'b': 3, 'c': 2, 'a': 1})
 734 
 735         '''
 736         if not isinstance(other, Counter):
 737             return NotImplemented
 738         result = Counter()
 739         for elem, count in self.items():
 740             other_count = other[elem]
 741             newcount = other_count if count < other_count else count
 742             if newcount > 0:
 743                 result[elem] = newcount
 744         for elem, count in other.items():
 745             if elem not in self and count > 0:
 746                 result[elem] = count
 747         return result
 748 
 749     def __and__(self, other):
 750         ''' Intersection is the minimum of corresponding counts.
 751 
 752         >>> Counter('abbb') & Counter('bcc')
 753         Counter({'b': 1})
 754 
 755         '''
 756         if not isinstance(other, Counter):
 757             return NotImplemented
 758         result = Counter()
 759         for elem, count in self.items():
 760             other_count = other[elem]
 761             newcount = count if count < other_count else other_count
 762             if newcount > 0:
 763                 result[elem] = newcount
 764         return result
 765 
 766     def __pos__(self):
 767         'Adds an empty counter, effectively stripping negative and zero counts'
 768         result = Counter()
 769         for elem, count in self.items():
 770             if count > 0:
 771                 result[elem] = count
 772         return result
 773 
 774     def __neg__(self):
 775         '''Subtracts from an empty counter.  Strips positive and zero counts,
 776         and flips the sign on negative counts.
 777 
 778         '''
 779         result = Counter()
 780         for elem, count in self.items():
 781             if count < 0:
 782                 result[elem] = 0 - count
 783         return result
 784 
 785     def _keep_positive(self):
 786         '''Internal method to strip elements with a negative or zero count'''
 787         nonpositive = [elem for elem, count in self.items() if not count > 0]
 788         for elem in nonpositive:
 789             del self[elem]
 790         return self
 791 
 792     def __iadd__(self, other):
 793         '''Inplace add from another counter, keeping only positive counts.
 794 
 795         >>> c = Counter('abbb')
 796         >>> c += Counter('bcc')
 797         >>> c
 798         Counter({'b': 4, 'c': 2, 'a': 1})
 799 
 800         '''
 801         for elem, count in other.items():
 802             self[elem] += count
 803         return self._keep_positive()
 804 
 805     def __isub__(self, other):
 806         '''Inplace subtract counter, but keep only results with positive counts.
 807 
 808         >>> c = Counter('abbbc')
 809         >>> c -= Counter('bccd')
 810         >>> c
 811         Counter({'b': 2, 'a': 1})
 812 
 813         '''
 814         for elem, count in other.items():
 815             self[elem] -= count
 816         return self._keep_positive()
 817 
 818     def __ior__(self, other):
 819         '''Inplace union is the maximum of value from either counter.
 820 
 821         >>> c = Counter('abbb')
 822         >>> c |= Counter('bcc')
 823         >>> c
 824         Counter({'b': 3, 'c': 2, 'a': 1})
 825 
 826         '''
 827         for elem, other_count in other.items():
 828             count = self[elem]
 829             if other_count > count:
 830                 self[elem] = other_count
 831         return self._keep_positive()
 832 
 833     def __iand__(self, other):
 834         '''Inplace intersection is the minimum of corresponding counts.
 835 
 836         >>> c = Counter('abbb')
 837         >>> c &= Counter('bcc')
 838         >>> c
 839         Counter({'b': 1})
 840 
 841         '''
 842         for elem, count in self.items():
 843             other_count = other[elem]
 844             if other_count < count:
 845                 self[elem] = other_count
 846         return self._keep_positive()
 847 
 848 
 849 ########################################################################
 850 ###  ChainMap
 851 ########################################################################
 852 
 853 class ChainMap(MutableMapping):
 854     ''' A ChainMap groups multiple dicts (or other mappings) together
 855     to create a single, updateable view.
 856 
 857     The underlying mappings are stored in a list.  That list is public and can
 858     be accessed or updated using the *maps* attribute.  There is no other
 859     state.
 860 
 861     Lookups search the underlying mappings successively until a key is found.
 862     In contrast, writes, updates, and deletions only operate on the first
 863     mapping.
 864 
 865     '''
 866 
 867     def __init__(self, *maps):
 868         '''Initialize a ChainMap by setting *maps* to the given mappings.
 869         If no mappings are provided, a single empty dictionary is used.
 870 
 871         '''
 872         self.maps = list(maps) or [{}]          # always at least one map
 873 
 874     def __missing__(self, key):
 875         raise KeyError(key)
 876 
 877     def __getitem__(self, key):
 878         for mapping in self.maps:
 879             try:
 880                 return mapping[key]             # can't use 'key in mapping' with defaultdict
 881             except KeyError:
 882                 pass
 883         return self.__missing__(key)            # support subclasses that define __missing__
 884 
 885     def get(self, key, default=None):
 886         return self[key] if key in self else default
 887 
 888     def __len__(self):
 889         return len(set().union(*self.maps))     # reuses stored hash values if possible
 890 
 891     def __iter__(self):
 892         return iter(set().union(*self.maps))
 893 
 894     def __contains__(self, key):
 895         return any(key in m for m in self.maps)
 896 
 897     def __bool__(self):
 898         return any(self.maps)
 899 
 900     @_recursive_repr()
 901     def __repr__(self):
 902         return '{0.__class__.__name__}({1})'.format(
 903             self, ', '.join(map(repr, self.maps)))
 904 
 905     @classmethod
 906     def fromkeys(cls, iterable, *args):
 907         'Create a ChainMap with a single dict created from the iterable.'
 908         return cls(dict.fromkeys(iterable, *args))
 909 
 910     def copy(self):
 911         'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
 912         return self.__class__(self.maps[0].copy(), *self.maps[1:])
 913 
 914     __copy__ = copy
 915 
 916     def new_child(self, m=None):                # like Django's Context.push()
 917         '''New ChainMap with a new map followed by all previous maps.
 918         If no map is provided, an empty dict is used.
 919         '''
 920         if m is None:
 921             m = {}
 922         return self.__class__(m, *self.maps)
 923 
 924     @property
 925     def parents(self):                          # like Django's Context.pop()
 926         'New ChainMap from maps[1:].'
 927         return self.__class__(*self.maps[1:])
 928 
 929     def __setitem__(self, key, value):
 930         self.maps[0][key] = value
 931 
 932     def __delitem__(self, key):
 933         try:
 934             del self.maps[0][key]
 935         except KeyError:
 936             raise KeyError('Key not found in the first mapping: {!r}'.format(key))
 937 
 938     def popitem(self):
 939         'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
 940         try:
 941             return self.maps[0].popitem()
 942         except KeyError:
 943             raise KeyError('No keys found in the first mapping.')
 944 
 945     def pop(self, key, *args):
 946         'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
 947         try:
 948             return self.maps[0].pop(key, *args)
 949         except KeyError:
 950             raise KeyError('Key not found in the first mapping: {!r}'.format(key))
 951 
 952     def clear(self):
 953         'Clear maps[0], leaving maps[1:] intact.'
 954         self.maps[0].clear()
 955 
 956 
 957 ################################################################################
 958 ### UserDict
 959 ################################################################################
 960 
 961 class UserDict(MutableMapping):
 962 
 963     # Start by filling-out the abstract methods
 964     def __init__(*args, **kwargs):
 965         if not args:
 966             raise TypeError("descriptor '__init__' of 'UserDict' object "
 967                             "needs an argument")
 968         self, *args = args
 969         if len(args) > 1:
 970             raise TypeError('expected at most 1 arguments, got %d' % len(args))
 971         if args:
 972             dict = args[0]
 973         elif 'dict' in kwargs:
 974             dict = kwargs.pop('dict')
 975             import warnings
 976             warnings.warn("Passing 'dict' as keyword argument is deprecated",
 977                           DeprecationWarning, stacklevel=2)
 978         else:
 979             dict = None
 980         self.data = {}
 981         if dict is not None:
 982             self.update(dict)
 983         if len(kwargs):
 984             self.update(kwargs)
 985     def __len__(self): return len(self.data)
 986     def __getitem__(self, key):
 987         if key in self.data:
 988             return self.data[key]
 989         if hasattr(self.__class__, "__missing__"):
 990             return self.__class__.__missing__(self, key)
 991         raise KeyError(key)
 992     def __setitem__(self, key, item): self.data[key] = item
 993     def __delitem__(self, key): del self.data[key]
 994     def __iter__(self):
 995         return iter(self.data)
 996 
 997     # Modify __contains__ to work correctly when __missing__ is present
 998     def __contains__(self, key):
 999         return key in self.data
1000 
1001     # Now, add the methods in dicts but not in MutableMapping
1002     def __repr__(self): return repr(self.data)
1003     def copy(self):
1004         if self.__class__ is UserDict:
1005             return UserDict(self.data.copy())
1006         import copy
1007         data = self.data
1008         try:
1009             self.data = {}
1010             c = copy.copy(self)
1011         finally:
1012             self.data = data
1013         c.update(self)
1014         return c
1015     @classmethod
1016     def fromkeys(cls, iterable, value=None):
1017         d = cls()
1018         for key in iterable:
1019             d[key] = value
1020         return d
1021 
1022 
1023 
1024 ################################################################################
1025 ### UserList
1026 ################################################################################
1027 
1028 class UserList(MutableSequence):
1029     """A more or less complete user-defined wrapper around list objects."""
1030     def __init__(self, initlist=None):
1031         self.data = []
1032         if initlist is not None:
1033             # XXX should this accept an arbitrary sequence?
1034             if type(initlist) == type(self.data):
1035                 self.data[:] = initlist
1036             elif isinstance(initlist, UserList):
1037                 self.data[:] = initlist.data[:]
1038             else:
1039                 self.data = list(initlist)
1040     def __repr__(self): return repr(self.data)
1041     def __lt__(self, other): return self.data <  self.__cast(other)
1042     def __le__(self, other): return self.data <= self.__cast(other)
1043     def __eq__(self, other): return self.data == self.__cast(other)
1044     def __gt__(self, other): return self.data >  self.__cast(other)
1045     def __ge__(self, other): return self.data >= self.__cast(other)
1046     def __cast(self, other):
1047         return other.data if isinstance(other, UserList) else other
1048     def __contains__(self, item): return item in self.data
1049     def __len__(self): return len(self.data)
1050     def __getitem__(self, i): return self.data[i]
1051     def __setitem__(self, i, item): self.data[i] = item
1052     def __delitem__(self, i): del self.data[i]
1053     def __add__(self, other):
1054         if isinstance(other, UserList):
1055             return self.__class__(self.data + other.data)
1056         elif isinstance(other, type(self.data)):
1057             return self.__class__(self.data + other)
1058         return self.__class__(self.data + list(other))
1059     def __radd__(self, other):
1060         if isinstance(other, UserList):
1061             return self.__class__(other.data + self.data)
1062         elif isinstance(other, type(self.data)):
1063             return self.__class__(other + self.data)
1064         return self.__class__(list(other) + self.data)
1065     def __iadd__(self, other):
1066         if isinstance(other, UserList):
1067             self.data += other.data
1068         elif isinstance(other, type(self.data)):
1069             self.data += other
1070         else:
1071             self.data += list(other)
1072         return self
1073     def __mul__(self, n):
1074         return self.__class__(self.data*n)
1075     __rmul__ = __mul__
1076     def __imul__(self, n):
1077         self.data *= n
1078         return self
1079     def append(self, item): self.data.append(item)
1080     def insert(self, i, item): self.data.insert(i, item)
1081     def pop(self, i=-1): return self.data.pop(i)
1082     def remove(self, item): self.data.remove(item)
1083     def clear(self): self.data.clear()
1084     def copy(self): return self.__class__(self)
1085     def count(self, item): return self.data.count(item)
1086     def index(self, item, *args): return self.data.index(item, *args)
1087     def reverse(self): self.data.reverse()
1088     def sort(self, *args, **kwds): self.data.sort(*args, **kwds)
1089     def extend(self, other):
1090         if isinstance(other, UserList):
1091             self.data.extend(other.data)
1092         else:
1093             self.data.extend(other)
1094 
1095 
1096 
1097 ################################################################################
1098 ### UserString
1099 ################################################################################
1100 
1101 class UserString(Sequence):
1102     def __init__(self, seq):
1103         if isinstance(seq, str):
1104             self.data = seq
1105         elif isinstance(seq, UserString):
1106             self.data = seq.data[:]
1107         else:
1108             self.data = str(seq)
1109     def __str__(self): return str(self.data)
1110     def __repr__(self): return repr(self.data)
1111     def __int__(self): return int(self.data)
1112     def __float__(self): return float(self.data)
1113     def __complex__(self): return complex(self.data)
1114     def __hash__(self): return hash(self.data)
1115     def __getnewargs__(self):
1116         return (self.data[:],)
1117 
1118     def __eq__(self, string):
1119         if isinstance(string, UserString):
1120             return self.data == string.data
1121         return self.data == string
1122     def __lt__(self, string):
1123         if isinstance(string, UserString):
1124             return self.data < string.data
1125         return self.data < string
1126     def __le__(self, string):
1127         if isinstance(string, UserString):
1128             return self.data <= string.data
1129         return self.data <= string
1130     def __gt__(self, string):
1131         if isinstance(string, UserString):
1132             return self.data > string.data
1133         return self.data > string
1134     def __ge__(self, string):
1135         if isinstance(string, UserString):
1136             return self.data >= string.data
1137         return self.data >= string
1138 
1139     def __contains__(self, char):
1140         if isinstance(char, UserString):
1141             char = char.data
1142         return char in self.data
1143 
1144     def __len__(self): return len(self.data)
1145     def __getitem__(self, index): return self.__class__(self.data[index])
1146     def __add__(self, other):
1147         if isinstance(other, UserString):
1148             return self.__class__(self.data + other.data)
1149         elif isinstance(other, str):
1150             return self.__class__(self.data + other)
1151         return self.__class__(self.data + str(other))
1152     def __radd__(self, other):
1153         if isinstance(other, str):
1154             return self.__class__(other + self.data)
1155         return self.__class__(str(other) + self.data)
1156     def __mul__(self, n):
1157         return self.__class__(self.data*n)
1158     __rmul__ = __mul__
1159     def __mod__(self, args):
1160         return self.__class__(self.data % args)
1161     def __rmod__(self, format):
1162         return self.__class__(format % args)
1163 
1164     # the following methods are defined in alphabetical order:
1165     def capitalize(self): return self.__class__(self.data.capitalize())
1166     def casefold(self):
1167         return self.__class__(self.data.casefold())
1168     def center(self, width, *args):
1169         return self.__class__(self.data.center(width, *args))
1170     def count(self, sub, start=0, end=_sys.maxsize):
1171         if isinstance(sub, UserString):
1172             sub = sub.data
1173         return self.data.count(sub, start, end)
1174     def encode(self, encoding=None, errors=None): # XXX improve this?
1175         if encoding:
1176             if errors:
1177                 return self.__class__(self.data.encode(encoding, errors))
1178             return self.__class__(self.data.encode(encoding))
1179         return self.__class__(self.data.encode())
1180     def endswith(self, suffix, start=0, end=_sys.maxsize):
1181         return self.data.endswith(suffix, start, end)
1182     def expandtabs(self, tabsize=8):
1183         return self.__class__(self.data.expandtabs(tabsize))
1184     def find(self, sub, start=0, end=_sys.maxsize):
1185         if isinstance(sub, UserString):
1186             sub = sub.data
1187         return self.data.find(sub, start, end)
1188     def format(self, *args, **kwds):
1189         return self.data.format(*args, **kwds)
1190     def format_map(self, mapping):
1191         return self.data.format_map(mapping)
1192     def index(self, sub, start=0, end=_sys.maxsize):
1193         return self.data.index(sub, start, end)
1194     def isalpha(self): return self.data.isalpha()
1195     def isalnum(self): return self.data.isalnum()
1196     def isdecimal(self): return self.data.isdecimal()
1197     def isdigit(self): return self.data.isdigit()
1198     def isidentifier(self): return self.data.isidentifier()
1199     def islower(self): return self.data.islower()
1200     def isnumeric(self): return self.data.isnumeric()
1201     def isprintable(self): return self.data.isprintable()
1202     def isspace(self): return self.data.isspace()
1203     def istitle(self): return self.data.istitle()
1204     def isupper(self): return self.data.isupper()
1205     def join(self, seq): return self.data.join(seq)
1206     def ljust(self, width, *args):
1207         return self.__class__(self.data.ljust(width, *args))
1208     def lower(self): return self.__class__(self.data.lower())
1209     def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1210     maketrans = str.maketrans
1211     def partition(self, sep):
1212         return self.data.partition(sep)
1213     def replace(self, old, new, maxsplit=-1):
1214         if isinstance(old, UserString):
1215             old = old.data
1216         if isinstance(new, UserString):
1217             new = new.data
1218         return self.__class__(self.data.replace(old, new, maxsplit))
1219     def rfind(self, sub, start=0, end=_sys.maxsize):
1220         if isinstance(sub, UserString):
1221             sub = sub.data
1222         return self.data.rfind(sub, start, end)
1223     def rindex(self, sub, start=0, end=_sys.maxsize):
1224         return self.data.rindex(sub, start, end)
1225     def rjust(self, width, *args):
1226         return self.__class__(self.data.rjust(width, *args))
1227     def rpartition(self, sep):
1228         return self.data.rpartition(sep)
1229     def rstrip(self, chars=None):
1230         return self.__class__(self.data.rstrip(chars))
1231     def split(self, sep=None, maxsplit=-1):
1232         return self.data.split(sep, maxsplit)
1233     def rsplit(self, sep=None, maxsplit=-1):
1234         return self.data.rsplit(sep, maxsplit)
1235     def splitlines(self, keepends=False): return self.data.splitlines(keepends)
1236     def startswith(self, prefix, start=0, end=_sys.maxsize):
1237         return self.data.startswith(prefix, start, end)
1238     def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1239     def swapcase(self): return self.__class__(self.data.swapcase())
1240     def title(self): return self.__class__(self.data.title())
1241     def translate(self, *args):
1242         return self.__class__(self.data.translate(*args))
1243     def upper(self): return self.__class__(self.data.upper())
1244     def zfill(self, width): return self.__class__(self.data.zfill(width))
collections

 

posted on 2018-05-22 23:01  lmgsanm  阅读(320)  评论(0编辑  收藏  举报