标签:from elements rabl signature tuple *args modify passing pac
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))
标签:from elements rabl signature tuple *args modify passing pac
原文地址:https://www.cnblogs.com/lmgsanm/p/9074659.html