1
'''This module implements specialized container datatypes providing
2
alternatives to Python's general purpose built-in containers, dict,
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
29
import _collections_abc
32
_sys.modules['collections.abc'] = _collections_abc
33
abc = _collections_abc
35
lazy from copy import copy as _copy
36
lazy from heapq import nlargest as _nlargest
37
from itertools import chain as _chain
38
from itertools import repeat as _repeat
39
from itertools import starmap as _starmap
40
from keyword import iskeyword as _iskeyword
41
from operator import eq as _eq
42
from operator import itemgetter as _itemgetter
43
from reprlib import recursive_repr as _recursive_repr
44
from _weakref import proxy as _proxy
47
from _collections import deque
51
_collections_abc.MutableSequence.register(deque)
54
# Expose _deque_iterator to support pickling deque iterators
55
from _collections import _deque_iterator # noqa: F401
60
from _collections import defaultdict
65
################################################################################
67
################################################################################
69
class _OrderedDictKeysView(_collections_abc.KeysView):
71
def __reversed__(self):
72
yield from reversed(self._mapping)
74
class _OrderedDictItemsView(_collections_abc.ItemsView):
76
def __reversed__(self):
77
for key in reversed(self._mapping):
78
yield (key, self._mapping[key])
80
class _OrderedDictValuesView(_collections_abc.ValuesView):
82
def __reversed__(self):
83
for key in reversed(self._mapping):
84
yield self._mapping[key]
87
__slots__ = 'prev', 'next', 'key', '__weakref__'
89
class OrderedDict(dict):
90
'Dictionary that remembers insertion order'
91
# An inherited dict maps keys to values.
92
# The inherited dict provides __getitem__, __len__, __contains__, and get.
93
# The remaining methods are order-aware.
94
# Big-O running times for all methods are the same as regular dictionaries.
96
# The internal self.__map dict maps keys to links in a doubly linked list.
97
# The circular doubly linked list starts and ends with a sentinel element.
98
# The sentinel element never gets deleted (this simplifies the algorithm).
99
# The sentinel is in self.__hardroot with a weakref proxy in self.__root.
100
# The prev links are weakref proxies (to prevent circular references).
101
# Individual links are kept alive by the hard reference in self.__map.
102
# Those hard references disappear when a key is deleted from an OrderedDict.
104
def __new__(cls, /, *args, **kwds):
105
"Create the ordered dict object and set up the underlying structures."
106
self = dict.__new__(cls)
107
self.__hardroot = _Link()
108
self.__root = root = _proxy(self.__hardroot)
109
root.prev = root.next = root
113
def __init__(self, other=(), /, **kwds):
114
'''Initialize an ordered dictionary. The signature is the same as
115
regular dictionaries. Keyword argument order is preserved.
117
self.__update(other, **kwds)
119
def __setitem__(self, key, value,
120
dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
121
'od.__setitem__(i, y) <==> od[i]=y'
122
# Setting a new item creates a new link at the end of the linked list,
123
# and the inherited dictionary is updated with the new key/value pair.
125
self.__map[key] = link = Link()
128
link.prev, link.next, link.key = last, root, key
130
root.prev = proxy(link)
131
dict_setitem(self, key, value)
133
def __delitem__(self, key, dict_delitem=dict.__delitem__):
134
'od.__delitem__(y) <==> del od[y]'
135
# Deleting an existing item uses self.__map to find the link which gets
136
# removed by updating the links in the predecessor and successor nodes.
137
dict_delitem(self, key)
138
link = self.__map.pop(key)
139
link_prev = link.prev
140
link_next = link.next
141
link_prev.next = link_next
142
link_next.prev = link_prev
147
'od.__iter__() <==> iter(od)'
148
# Traverse the linked list in order.
151
while curr is not root:
155
def __reversed__(self):
156
'od.__reversed__() <==> reversed(od)'
157
# Traverse the linked list in reverse order.
160
while curr is not root:
165
'od.clear() -> None. Remove all items from od.'
167
root.prev = root.next = root
171
def popitem(self, last=True):
172
'''Remove and return a (key, value) pair from the dictionary.
174
Pairs are returned in LIFO order if last is true or FIFO order if false.
177
raise KeyError('dictionary is empty')
181
link_prev = link.prev
182
link_prev.next = root
183
root.prev = link_prev
186
link_next = link.next
187
root.next = link_next
188
link_next.prev = root
191
value = dict.pop(self, key)
194
def move_to_end(self, key, last=True):
195
'''Move an existing element to the end (or beginning if last is false).
197
Raise KeyError if the element does not exist.
199
link = self.__map[key]
200
link_prev = link.prev
201
link_next = link.next
202
soft_link = link_next.prev
203
link_prev.next = link_next
204
link_next.prev = link_prev
210
root.prev = soft_link
216
first.prev = soft_link
219
def __sizeof__(self):
220
sizeof = _sys.getsizeof
221
n = len(self) + 1 # number of links including root
222
size = sizeof(self.__dict__) # instance dictionary
223
size += sizeof(self.__map) * 2 # internal dict and inherited dict
224
size += sizeof(self.__hardroot) * n # link objects
225
size += sizeof(self.__root) * n # proxy objects
228
update = __update = _collections_abc.MutableMapping.update
231
"D.keys() -> a set-like object providing a view on D's keys"
232
return _OrderedDictKeysView(self)
235
"D.items() -> a set-like object providing a view on D's items"
236
return _OrderedDictItemsView(self)
239
"D.values() -> an object providing a view on D's values"
240
return _OrderedDictValuesView(self)
242
__ne__ = _collections_abc.MutableMapping.__ne__
246
def pop(self, key, default=__marker):
247
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding
248
value. If key is not found, d is returned if given, otherwise KeyError
252
marker = self.__marker
253
result = dict.pop(self, key, marker)
254
if result is not marker:
255
# The same as in __delitem__().
256
link = self.__map.pop(key)
257
link_prev = link.prev
258
link_next = link.next
259
link_prev.next = link_next
260
link_next.prev = link_prev
264
if default is marker:
268
def setdefault(self, key, default=None):
269
'''Insert key with a value of default if key is not in the dictionary.
271
Return the value for key if key is in the dictionary, else default.
280
'od.__repr__() <==> repr(od)'
282
return '%s()' % (self.__class__.__name__,)
283
return '%s(%r)' % (self.__class__.__name__, dict(self.items()))
285
def __reduce__(self):
286
'Return state information for pickling'
287
state = self.__getstate__()
289
if isinstance(state, tuple):
295
for k in vars(OrderedDict()):
301
state = state or None
302
return self.__class__, (), state, None, iter(self.items())
305
'od.copy() -> a shallow copy of od'
306
return self.__class__(self)
309
def fromkeys(cls, iterable, value=None):
310
'''Create a new ordered dictionary with keys from iterable and values set to value.
317
def __eq__(self, other):
318
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
319
while comparison to a regular mapping is order-insensitive.
322
if isinstance(other, OrderedDict):
323
return dict.__eq__(self, other) and all(map(_eq, self, other))
324
return dict.__eq__(self, other)
326
def __ior__(self, other):
330
def __or__(self, other):
331
if not isinstance(other, (dict, frozendict)):
332
return NotImplemented
333
new = self.__class__(self)
337
def __ror__(self, other):
338
if not isinstance(other, (dict, frozendict)):
339
return NotImplemented
340
new = self.__class__(other)
346
from _collections import OrderedDict
348
# Leave the pure Python version in place.
352
################################################################################
354
################################################################################
357
from _collections import _tuplegetter
359
_tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc)
361
def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):
362
"""Returns a new subclass of tuple with named fields.
364
>>> Point = namedtuple('Point', ['x', 'y'])
365
>>> Point.__doc__ # docstring for the new class
367
>>> p = Point(11, y=22) # instantiate with positional args or keywords
368
>>> p[0] + p[1] # indexable like a plain tuple
370
>>> x, y = p # unpack like a regular tuple
373
>>> p.x + p.y # fields also accessible by name
375
>>> d = p._asdict() # convert to a dictionary
378
>>> Point(**d) # convert from a dictionary
380
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
385
# Validate the field names. At the user's option, either generate an error
386
# message or automatically replace the field name with a valid name.
387
if isinstance(field_names, str):
388
field_names = field_names.replace(',', ' ').split()
389
field_names = list(map(str, field_names))
390
typename = _sys.intern(str(typename))
394
for index, name in enumerate(field_names):
395
if (not name.isidentifier()
397
or name.startswith('_')
399
field_names[index] = f'_{index}'
402
for name in [typename] + field_names:
403
if type(name) is not str:
404
raise TypeError('Type names and field names must be strings')
405
if not name.isidentifier():
406
raise ValueError('Type names and field names must be valid '
407
f'identifiers: {name!r}')
409
raise ValueError('Type names and field names cannot be a '
410
f'keyword: {name!r}')
413
for name in field_names:
414
if name.startswith('_') and not rename:
415
raise ValueError('Field names cannot start with an underscore: '
418
raise ValueError(f'Encountered duplicate field name: {name!r}')
422
if defaults is not None:
423
defaults = tuple(defaults)
424
if len(defaults) > len(field_names):
425
raise TypeError('Got more default values than field names')
426
field_defaults = dict(reversed(list(zip(reversed(field_names),
427
reversed(defaults)))))
429
# Variables used in the methods and docstrings
430
field_names = tuple(map(_sys.intern, field_names))
431
num_fields = len(field_names)
432
arg_list = ', '.join(field_names)
435
repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')'
436
tuple_new = tuple.__new__
437
_dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip
439
# Create all the named tuple methods to be added to the class namespace
442
'_tuple_new': tuple_new,
444
'__name__': f'namedtuple_{typename}',
446
code = f'lambda _cls, {arg_list}: _tuple_new(_cls, ({arg_list}))'
447
__new__ = eval(code, namespace)
448
__new__.__name__ = '__new__'
449
__new__.__doc__ = f'Create new instance of {typename}({arg_list})'
450
if defaults is not None:
451
__new__.__defaults__ = defaults
454
def _make(cls, iterable):
455
result = tuple_new(cls, iterable)
456
if _len(result) != num_fields:
457
raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')
460
_make.__func__.__doc__ = (f'Make a new {typename} object from a sequence '
463
def _replace(self, /, **kwds):
464
result = self._make(_map(kwds.pop, field_names, self))
466
raise TypeError(f'Got unexpected field names: {list(kwds)!r}')
469
_replace.__doc__ = (f'Return a new {typename} object replacing specified '
470
'fields with new values')
473
'Return a nicely formatted representation string'
474
return self.__class__.__name__ + repr_fmt % self
477
'Return a new dict which maps field names to their values.'
478
return _dict(_zip(self._fields, self))
480
def __getnewargs__(self):
481
'Return self as a plain tuple. Used by copy and pickle.'
484
# Modify function metadata to help with introspection and debugging
493
method.__qualname__ = f'{typename}.{method.__name__}'
495
# Build-up the class namespace dictionary
496
# and use type() to build the result class
498
'__doc__': f'{typename}({arg_list})',
500
'_fields': field_names,
501
'_field_defaults': field_defaults,
504
'__replace__': _replace,
505
'_replace': _replace,
506
'__repr__': __repr__,
508
'__getnewargs__': __getnewargs__,
509
'__match_args__': field_names,
511
for index, name in enumerate(field_names):
512
doc = _sys.intern(f'Alias for field number {index}')
513
class_namespace[name] = _tuplegetter(index, doc)
515
result = type(typename, (tuple,), class_namespace)
517
# For pickling to work, the __module__ variable needs to be set to the frame
518
# where the named tuple is created. Bypass this step in environments where
519
# sys._getframe is not defined (Jython for example) or sys._getframe is not
520
# defined for arguments greater than 0 (IronPython), or where the user has
521
# specified a particular module.
524
module = _sys._getframemodulename(1) or '__main__'
525
except AttributeError:
527
module = _sys._getframe(1).f_globals.get('__name__', '__main__')
528
except (AttributeError, ValueError):
530
if module is not None:
531
result.__module__ = module
536
########################################################################
538
########################################################################
540
def _count_elements(mapping, iterable):
541
'Tally elements from the iterable.'
542
mapping_get = mapping.get
543
for elem in iterable:
544
mapping[elem] = mapping_get(elem, 0) + 1
546
try: # Load C helper function if available
547
from _collections import _count_elements
552
'''Dict subclass for counting hashable items. Sometimes called a bag
553
or multiset. Elements are stored as dictionary keys and their counts
554
are stored as dictionary values.
556
When constructed from a Mapping or Counter, the original object's
557
values will be used as the initial counts.
559
>>> c = Counter('abcdeabcdabcaba') # count elements from a string
561
>>> c.most_common(3) # three most common elements
562
[('a', 5), ('b', 4), ('c', 3)]
563
>>> sorted(c) # list all unique elements
564
['a', 'b', 'c', 'd', 'e']
565
>>> ''.join(sorted(c.elements())) # list elements with repetitions
567
>>> sum(c.values()) # total of all counts
570
>>> c['a'] # count of letter 'a'
572
>>> for elem in 'shazam': # update counts from an iterable
573
... c[elem] += 1 # by adding 1 to each element's count
574
>>> c['a'] # now there are seven 'a'
576
>>> del c['b'] # remove all 'b'
577
>>> c['b'] # now there are zero 'b'
580
>>> d = Counter('simsalabim') # make another counter
581
>>> c.update(d) # add in the second counter
582
>>> c['a'] # now there are nine 'a'
585
>>> c.clear() # empty the counter
589
Note: If a count is set to zero or reduced to zero, it will remain
590
in the counter until the entry is deleted or the counter is cleared:
592
>>> c = Counter('aaabbc')
593
>>> c['b'] -= 2 # reduce the count of 'b' by two
594
>>> c.most_common() # 'b' is still in, but its count is zero
595
[('a', 3), ('c', 1), ('b', 0)]
599
# http://en.wikipedia.org/wiki/Multiset
600
# http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
601
# http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
602
# http://code.activestate.com/recipes/259174/
603
# Knuth, TAOCP Vol. II section 4.6.3
605
def __init__(self, iterable=None, /, **kwds):
606
'''Create a new, empty Counter object. And if given, count elements
607
from an input iterable. Or, initialize the count from another mapping
608
of elements to their counts.
610
>>> c = Counter() # a new, empty counter
611
>>> c = Counter('gallahad') # a new counter from an iterable
612
>>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
613
>>> c = Counter(a=4, b=2) # a new counter from keyword args
617
2
89
self.update(iterable, **kwds)
619
def __missing__(self, key):
620
'The count of elements not in the Counter is zero.'
621
# Needed so that self[missing_item] does not raise KeyError
626
return sum(self.values())
628
def most_common(self, n=None):
629
'''List the n most common elements and their counts from the most
630
common to the least. If n is None, then list all element counts.
632
>>> Counter('abracadabra').most_common(3)
633
[('a', 5), ('b', 2), ('r', 2)]
636
# Emulate Bag.sortedByCount from Smalltalk
638
return sorted(self.items(), key=_itemgetter(1), reverse=True)
640
return _nlargest(n, self.items(), key=_itemgetter(1))
643
'''Iterator over elements repeating each as many times as its count.
645
>>> c = Counter('ABCABC')
646
>>> sorted(c.elements())
647
['A', 'A', 'B', 'B', 'C', 'C']
649
Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
652
>>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
653
>>> math.prod(prime_factors.elements())
656
Note, if an element's count has been set to zero or is a negative
657
number, elements() will ignore it.
660
# Emulate Bag.do from Smalltalk and Multiset.begin from C++.
661
return _chain.from_iterable(_starmap(_repeat, self.items()))
663
# Override dict methods where necessary
666
def fromkeys(cls, iterable, v=None):
667
# There is no equivalent method for counters because the semantics
668
# would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2).
669
# Initializing counters to zero values isn't necessary because zero
670
# is already the default value for counter lookups. Initializing
671
# to one is easily accomplished with Counter(set(iterable)). For
672
# more exotic cases, create a dictionary first using a dictionary
673
# comprehension or dict.fromkeys().
674
raise NotImplementedError(
675
'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
677
def update(self, iterable=None, /, **kwds):
678
'''Like dict.update() but add counts instead of replacing them.
680
Source can be an iterable, a dictionary, or another Counter instance.
682
>>> c = Counter('which')
683
>>> c.update('witch') # add elements from another iterable
684
>>> d = Counter('watch')
685
>>> c.update(d) # add elements from another counter
686
>>> c['h'] # four 'h' in which, witch, and watch
690
# The regular dict.update() operation makes no sense here because the
691
# replace behavior results in some of the original untouched counts
692
# being mixed-in with all of the other counts for a mismash that
693
# doesn't have a straight-forward interpretation in most counting
694
# contexts. Instead, we implement straight-addition. Both the inputs
695
# and outputs are allowed to contain zero and negative counts.
697
if iterable is not None:
698
if isinstance(iterable, _collections_abc.Mapping):
701
for elem, count in iterable.items():
702
self[elem] = count + self_get(elem, 0)
704
# fast path when counter is empty
705
super().update(iterable)
707
87
87
_count_elements(self, iterable)
711
def subtract(self, iterable=None, /, **kwds):
712
'''Like dict.update() but subtracts counts instead of replacing them.
713
Counts can be reduced below zero. Both the inputs and outputs are
714
allowed to contain zero and negative counts.
716
Source can be an iterable, a dictionary, or another Counter instance.
718
>>> c = Counter('which')
719
>>> c.subtract('witch') # subtract elements from another iterable
720
>>> c.subtract(Counter('watch')) # subtract elements from another counter
721
>>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
723
>>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
727
if iterable is not None:
729
if isinstance(iterable, _collections_abc.Mapping):
730
for elem, count in iterable.items():
731
self[elem] = self_get(elem, 0) - count
733
for elem in iterable:
734
self[elem] = self_get(elem, 0) - 1
739
'Return a shallow copy.'
740
return self.__class__(self)
742
def __reduce__(self):
743
return self.__class__, (dict(self),)
745
def __delitem__(self, elem):
746
'Like dict.__delitem__() but does not raise KeyError for missing values.'
748
super().__delitem__(elem)
752
return f'{self.__class__.__name__}()'
754
# dict() preserves the ordering returned by most_common()
755
d = dict(self.most_common())
757
# handle case where values are not orderable
759
return f'{self.__class__.__name__}({d!r})'
761
# Multiset-style mathematical operations discussed in:
762
# Knuth TAOCP Volume II section 4.6.3 exercise 19
763
# and at http://en.wikipedia.org/wiki/Multiset
765
# Outputs guaranteed to only include positive counts.
767
# To strip negative and zero counts, add-in an empty counter:
770
# Results are ordered according to when an element is first
771
# encountered in the left operand and then by the order
772
# encountered in the right operand.
774
# When the multiplicities are all zero or one, multiset operations
775
# are guaranteed to be equivalent to the corresponding operations
778
# Given counter multisets such as:
779
# cp = Counter(a=1, b=0, c=1)
780
# cq = Counter(c=1, d=0, e=1)
782
# The corresponding regular sets would be:
786
# All of the following relations would hold:
787
# (cp == cq) == (sp == sq)
788
# (cp != cq) == (sp != sq)
789
# (cp <= cq) == (sp <= sq)
790
# (cp < cq) == (sp < sq)
791
# (cp >= cq) == (sp >= sq)
792
# (cp > cq) == (sp > sq)
793
# set(cp + cq) == sp | sq
794
# set(cp - cq) == sp - sq
795
# set(cp | cq) == sp | sq
796
# set(cp & cq) == sp & sq
797
# set(cp ^ cq) == sp ^ sq
799
def __eq__(self, other):
800
'True if all counts agree. Missing counts are treated as zero.'
801
if not isinstance(other, Counter):
802
return NotImplemented
803
return all(self[e] == other[e] for c in (self, other) for e in c)
805
def __ne__(self, other):
806
'True if any counts disagree. Missing counts are treated as zero.'
807
if not isinstance(other, Counter):
808
return NotImplemented
809
return not self == other
811
def __le__(self, other):
812
'True if all counts in self are a subset of those in other.'
813
if not isinstance(other, Counter):
814
return NotImplemented
815
return all(self[e] <= other[e] for c in (self, other) for e in c)
817
def __lt__(self, other):
818
'True if all counts in self are a proper subset of those in other.'
819
if not isinstance(other, Counter):
820
return NotImplemented
821
return self <= other and self != other
823
def __ge__(self, other):
824
'True if all counts in self are a superset of those in other.'
825
if not isinstance(other, Counter):
826
return NotImplemented
827
return all(self[e] >= other[e] for c in (self, other) for e in c)
829
def __gt__(self, other):
830
'True if all counts in self are a proper superset of those in other.'
831
if not isinstance(other, Counter):
832
return NotImplemented
833
return self >= other and self != other
835
def __add__(self, other):
836
'''Add counts from two counters.
838
>>> Counter('abbb') + Counter('bcc')
839
Counter({'b': 4, 'c': 2, 'a': 1})
842
if not isinstance(other, Counter):
843
return NotImplemented
845
for elem, count in self.items():
846
newcount = count + other[elem]
848
result[elem] = newcount
849
for elem, count in other.items():
850
if elem not in self and count > 0:
854
def __sub__(self, other):
855
''' Subtract count, but keep only results with positive counts.
857
>>> Counter('abbbc') - Counter('bccd')
858
Counter({'b': 2, 'a': 1})
861
if not isinstance(other, Counter):
862
return NotImplemented
864
for elem, count in self.items():
865
newcount = count - other[elem]
867
result[elem] = newcount
868
for elem, count in other.items():
869
if elem not in self and count < 0:
870
result[elem] = 0 - count
873
def __or__(self, other):
874
'''Union is the maximum of value in either of the input counters.
876
>>> Counter('abbb') | Counter('bcc')
877
Counter({'b': 3, 'c': 2, 'a': 1})
880
if not isinstance(other, Counter):
881
return NotImplemented
883
for elem, count in self.items():
884
other_count = other[elem]
885
newcount = other_count if count < other_count else count
887
result[elem] = newcount
888
for elem, count in other.items():
889
if elem not in self and count > 0:
893
def __and__(self, other):
894
''' Intersection is the minimum of corresponding counts.
896
>>> Counter('abbb') & Counter('bcc')
900
if not isinstance(other, Counter):
901
return NotImplemented
903
for elem, count in self.items():
904
other_count = other[elem]
905
newcount = count if count < other_count else other_count
907
result[elem] = newcount
910
def __xor__(self, other):
911
'''Symmetric difference. Absolute value of count differences.
913
The symmetric difference p ^ q is equivalent to:
917
For each element, symmetric difference gives the same result as:
919
max(p[elem], q[elem]) - min(p[elem], q[elem])
921
>>> Counter(a=5, b=3, c=2, d=2) ^ Counter(a=1, b=3, c=5, e=1)
922
Counter({'a': 4, 'c': 3, 'd': 2, 'e': 1})
925
if not isinstance(other, Counter):
926
return NotImplemented
928
for elem, count in self.items():
929
newcount = abs(count - other[elem])
931
result[elem] = newcount
932
for elem, count in other.items():
933
if elem not in self and count:
934
result[elem] = abs(count)
938
'Adds an empty counter, effectively stripping negative and zero counts'
940
for elem, count in self.items():
946
'''Subtracts from an empty counter. Strips positive and zero counts,
947
and flips the sign on negative counts.
951
for elem, count in self.items():
953
result[elem] = 0 - count
956
def _keep_positive(self):
957
'''Internal method to strip elements with a negative or zero count'''
958
nonpositive = [elem for elem, count in self.items() if not count > 0]
959
for elem in nonpositive:
963
def __iadd__(self, other):
964
'''Inplace add from another counter, keeping only positive counts.
966
>>> c = Counter('abbb')
967
>>> c += Counter('bcc')
969
Counter({'b': 4, 'c': 2, 'a': 1})
972
for elem, count in other.items():
974
return self._keep_positive()
976
def __isub__(self, other):
977
'''Inplace subtract counter, but keep only results with positive counts.
979
>>> c = Counter('abbbc')
980
>>> c -= Counter('bccd')
982
Counter({'b': 2, 'a': 1})
985
for elem, count in other.items():
987
return self._keep_positive()
989
def __ior__(self, other):
990
'''Inplace union is the maximum of value from either counter.
992
>>> c = Counter('abbb')
993
>>> c |= Counter('bcc')
995
Counter({'b': 3, 'c': 2, 'a': 1})
998
for elem, other_count in other.items():
1000
if other_count > count:
1001
self[elem] = other_count
1002
return self._keep_positive()
1004
def __iand__(self, other):
1005
'''Inplace intersection is the minimum of corresponding counts.
1007
>>> c = Counter('abbb')
1008
>>> c &= Counter('bcc')
1013
for elem, count in self.items():
1014
other_count = other[elem]
1015
if other_count < count:
1016
self[elem] = other_count
1017
return self._keep_positive()
1019
def __ixor__(self, other):
1020
'''Inplace symmetric difference. Absolute value of count differences.
1022
>>> c = Counter(a=5, b=3, c=2, d=2)
1023
>>> c ^= Counter(a=1, b=3, c=5, e=1)
1025
Counter({'a': 4, 'c': 3, 'd': 2, 'e': 1})
1028
for elem, count in self.items():
1029
self[elem] = abs(count - other[elem])
1030
for elem, count in other.items():
1031
if elem not in self:
1032
self[elem] = abs(count)
1033
return self._keep_positive()
1036
########################################################################
1038
########################################################################
1040
class ChainMap(_collections_abc.MutableMapping):
1041
''' A ChainMap groups multiple dicts (or other mappings) together
1042
to create a single, updateable view.
1044
The underlying mappings are stored in a list. That list is public and can
1045
be accessed or updated using the *maps* attribute. There is no other
1048
Lookups search the underlying mappings successively until a key is found.
1049
In contrast, writes, updates, and deletions only operate on the first
1054
def __init__(self, *maps):
1055
'''Initialize a ChainMap by setting *maps* to the given mappings.
1056
If no mappings are provided, a single empty dictionary is used.
1059
self.maps = list(maps) or [{}] # always at least one map
1061
def __missing__(self, key):
1064
def __getitem__(self, key):
1065
for mapping in self.maps:
1067
return mapping[key] # can't use 'key in mapping' with defaultdict
1070
return self.__missing__(key) # support subclasses that define __missing__
1072
def get(self, key, default=None):
1073
return self[key] if key in self else default # needs to make use of __contains__
1076
return len(set().union(*self.maps)) # reuses stored hash values if possible
1080
for mapping in map(dict.fromkeys, reversed(self.maps)):
1081
d |= mapping # reuses stored hash values if possible
1084
def __contains__(self, key):
1085
for mapping in self.maps:
1091
return any(self.maps)
1095
return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})'
1098
def fromkeys(cls, iterable, value=None, /):
1099
'Create a new ChainMap with keys from iterable and values set to value.'
1100
return cls(dict.fromkeys(iterable, value))
1103
'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
1104
return self.__class__(self.maps[0].copy(), *self.maps[1:])
1108
def new_child(self, m=None, **kwargs): # like Django's Context.push()
1109
'''New ChainMap with a new map followed by all previous maps.
1110
If no map is provided, an empty dict is used.
1111
Keyword arguments update the map or new empty dict.
1117
return self.__class__(m, *self.maps)
1120
def parents(self): # like Django's Context.pop()
1121
'New ChainMap from maps[1:].'
1122
return self.__class__(*self.maps[1:])
1124
def __setitem__(self, key, value):
1125
self.maps[0][key] = value
1127
def __delitem__(self, key):
1129
del self.maps[0][key]
1131
raise KeyError(f'Key not found in the first mapping: {key!r}')
1134
'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
1136
return self.maps[0].popitem()
1138
raise KeyError('No keys found in the first mapping.')
1140
def pop(self, key, *args):
1141
'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
1143
return self.maps[0].pop(key, *args)
1145
raise KeyError(f'Key not found in the first mapping: {key!r}')
1148
'Clear maps[0], leaving maps[1:] intact.'
1149
self.maps[0].clear()
1151
def __ior__(self, other):
1152
self.maps[0].update(other)
1155
def __or__(self, other):
1156
if not isinstance(other, _collections_abc.Mapping):
1157
return NotImplemented
1159
m.maps[0].update(other)
1162
def __ror__(self, other):
1163
if not isinstance(other, _collections_abc.Mapping):
1164
return NotImplemented
1166
for child in reversed(self.maps):
1168
return self.__class__(m)
1171
################################################################################
1173
################################################################################
1175
class UserDict(_collections_abc.MutableMapping):
1177
# Start by filling-out the abstract methods
1178
def __init__(self, dict=None, /, **kwargs):
1180
if dict is not None:
1186
return len(self.data)
1188
def __getitem__(self, key):
1189
if key in self.data:
1190
return self.data[key]
1191
if hasattr(self.__class__, "__missing__"):
1192
return self.__class__.__missing__(self, key)
1195
def __setitem__(self, key, item):
1196
self.data[key] = item
1198
def __delitem__(self, key):
1202
return iter(self.data)
1204
# Modify __contains__ and get() to work like dict
1205
# does when __missing__ is present.
1206
def __contains__(self, key):
1207
return key in self.data
1209
def get(self, key, default=None):
1215
# Now, add the methods in dicts but not in MutableMapping
1217
return repr(self.data)
1219
def __or__(self, other):
1220
if isinstance(other, UserDict):
1221
return self.__class__(self.data | other.data)
1222
if isinstance(other, (dict, frozendict)):
1223
return self.__class__(self.data | other)
1224
return NotImplemented
1226
def __ror__(self, other):
1227
if isinstance(other, UserDict):
1228
return self.__class__(other.data | self.data)
1229
if isinstance(other, (dict, frozendict)):
1230
return self.__class__(other | self.data)
1231
return NotImplemented
1233
def __ior__(self, other):
1234
if isinstance(other, UserDict):
1235
self.data |= other.data
1241
inst = self.__class__.__new__(self.__class__)
1242
inst.__dict__.update(self.__dict__)
1243
# Create a copy and avoid triggering descriptors
1244
inst.__dict__["data"] = self.__dict__["data"].copy()
1248
if self.__class__ is UserDict:
1249
return UserDict(self.data.copy())
1260
# This method has a default implementation in MutableMapping, but dict's
1261
# equivalent is last-in, first-out instead of first-in, first-out.
1263
"""Remove and return a (key, value) pair as a 2-tuple.
1265
Removes pairs in the same order as the wrapped mapping's popitem()
1266
method. For dict objects (the default), that order is last-in,
1268
Raises KeyError if the UserDict is empty.
1270
return self.data.popitem()
1274
def fromkeys(cls, iterable, value=None):
1276
for key in iterable:
1281
################################################################################
1283
################################################################################
1285
class UserList(_collections_abc.MutableSequence):
1286
"""A more or less complete user-defined wrapper around list objects."""
1288
def __init__(self, initlist=None):
1290
if initlist is not None:
1291
# XXX should this accept an arbitrary sequence?
1292
if type(initlist) == type(self.data):
1293
self.data[:] = initlist
1294
elif isinstance(initlist, UserList):
1295
self.data[:] = initlist.data[:]
1297
self.data = list(initlist)
1300
return repr(self.data)
1302
def __lt__(self, other):
1303
return self.data < self.__cast(other)
1305
def __le__(self, other):
1306
return self.data <= self.__cast(other)
1308
def __eq__(self, other):
1309
return self.data == self.__cast(other)
1311
def __gt__(self, other):
1312
return self.data > self.__cast(other)
1314
def __ge__(self, other):
1315
return self.data >= self.__cast(other)
1317
def __cast(self, other):
1318
return other.data if isinstance(other, UserList) else other
1320
def __contains__(self, item):
1321
return item in self.data
1324
return len(self.data)
1326
def __getitem__(self, i):
1327
if isinstance(i, slice):
1328
return self.__class__(self.data[i])
1332
def __setitem__(self, i, item):
1335
def __delitem__(self, i):
1338
def __add__(self, other):
1339
if isinstance(other, UserList):
1340
return self.__class__(self.data + other.data)
1341
elif isinstance(other, type(self.data)):
1342
return self.__class__(self.data + other)
1343
return self.__class__(self.data + list(other))
1345
def __radd__(self, other):
1346
if isinstance(other, UserList):
1347
return self.__class__(other.data + self.data)
1348
elif isinstance(other, type(self.data)):
1349
return self.__class__(other + self.data)
1350
return self.__class__(list(other) + self.data)
1352
def __iadd__(self, other):
1353
if isinstance(other, UserList):
1354
self.data += other.data
1355
elif isinstance(other, type(self.data)):
1358
self.data += list(other)
1361
def __mul__(self, n):
1362
return self.__class__(self.data * n)
1366
def __imul__(self, n):
1371
inst = self.__class__.__new__(self.__class__)
1372
inst.__dict__.update(self.__dict__)
1373
# Create a copy and avoid triggering descriptors
1374
inst.__dict__["data"] = self.__dict__["data"][:]
1377
def append(self, item):
1378
self.data.append(item)
1380
def insert(self, i, item):
1381
self.data.insert(i, item)
1383
def pop(self, i=-1):
1384
return self.data.pop(i)
1386
def remove(self, item):
1387
self.data.remove(item)
1393
return self.__class__(self)
1395
def count(self, item):
1396
return self.data.count(item)
1398
def index(self, item, *args):
1399
return self.data.index(item, *args)
1404
def sort(self, /, *args, **kwds):
1405
self.data.sort(*args, **kwds)
1407
def extend(self, other):
1408
if isinstance(other, UserList):
1409
self.data.extend(other.data)
1411
self.data.extend(other)
1414
################################################################################
1416
################################################################################
1418
class UserString(_collections_abc.Sequence):
1420
def __init__(self, seq):
1421
if isinstance(seq, str):
1423
elif isinstance(seq, UserString):
1424
self.data = seq.data[:]
1426
self.data = str(seq)
1429
return str(self.data)
1432
return repr(self.data)
1435
return int(self.data)
1437
def __float__(self):
1438
return float(self.data)
1440
def __complex__(self):
1441
return complex(self.data)
1444
return hash(self.data)
1446
def __getnewargs__(self):
1447
return (self.data[:],)
1449
def __eq__(self, string):
1450
if isinstance(string, UserString):
1451
return self.data == string.data
1452
return self.data == string
1454
def __lt__(self, string):
1455
if isinstance(string, UserString):
1456
return self.data < string.data
1457
return self.data < string
1459
def __le__(self, string):
1460
if isinstance(string, UserString):
1461
return self.data <= string.data
1462
return self.data <= string
1464
def __gt__(self, string):
1465
if isinstance(string, UserString):
1466
return self.data > string.data
1467
return self.data > string
1469
def __ge__(self, string):
1470
if isinstance(string, UserString):
1471
return self.data >= string.data
1472
return self.data >= string
1474
def __contains__(self, char):
1475
if isinstance(char, UserString):
1477
return char in self.data
1480
return len(self.data)
1482
def __getitem__(self, index):
1483
return self.__class__(self.data[index])
1485
def __add__(self, other):
1486
if isinstance(other, UserString):
1487
return self.__class__(self.data + other.data)
1488
elif isinstance(other, str):
1489
return self.__class__(self.data + other)
1490
return self.__class__(self.data + str(other))
1492
def __radd__(self, other):
1493
if isinstance(other, str):
1494
return self.__class__(other + self.data)
1495
return self.__class__(str(other) + self.data)
1497
def __mul__(self, n):
1498
return self.__class__(self.data * n)
1502
def __mod__(self, args):
1503
return self.__class__(self.data % args)
1505
def __rmod__(self, template):
1506
return self.__class__(str(template) % self)
1508
# the following methods are defined in alphabetical order:
1509
def capitalize(self):
1510
return self.__class__(self.data.capitalize())
1513
return self.__class__(self.data.casefold())
1515
def center(self, width, *args):
1516
return self.__class__(self.data.center(width, *args))
1518
def count(self, sub, start=0, end=_sys.maxsize):
1519
if isinstance(sub, UserString):
1521
return self.data.count(sub, start, end)
1523
def removeprefix(self, prefix, /):
1524
if isinstance(prefix, UserString):
1525
prefix = prefix.data
1526
return self.__class__(self.data.removeprefix(prefix))
1528
def removesuffix(self, suffix, /):
1529
if isinstance(suffix, UserString):
1530
suffix = suffix.data
1531
return self.__class__(self.data.removesuffix(suffix))
1533
def encode(self, encoding='utf-8', errors='strict'):
1534
encoding = 'utf-8' if encoding is None else encoding
1535
errors = 'strict' if errors is None else errors
1536
return self.data.encode(encoding, errors)
1538
def endswith(self, suffix, start=0, end=_sys.maxsize):
1539
return self.data.endswith(suffix, start, end)
1541
def expandtabs(self, tabsize=8):
1542
return self.__class__(self.data.expandtabs(tabsize))
1544
def find(self, sub, start=0, end=_sys.maxsize):
1545
if isinstance(sub, UserString):
1547
return self.data.find(sub, start, end)
1549
def format(self, /, *args, **kwds):
1550
return self.data.format(*args, **kwds)
1552
def format_map(self, mapping):
1553
return self.data.format_map(mapping)
1555
def index(self, sub, start=0, end=_sys.maxsize):
1556
if isinstance(sub, UserString):
1558
return self.data.index(sub, start, end)
1561
return self.data.isalpha()
1564
return self.data.isalnum()
1567
return self.data.isascii()
1569
def isdecimal(self):
1570
return self.data.isdecimal()
1573
return self.data.isdigit()
1575
def isidentifier(self):
1576
return self.data.isidentifier()
1579
return self.data.islower()
1581
def isnumeric(self):
1582
return self.data.isnumeric()
1584
def isprintable(self):
1585
return self.data.isprintable()
1588
return self.data.isspace()
1591
return self.data.istitle()
1594
return self.data.isupper()
1596
def join(self, seq):
1597
return self.data.join(seq)
1599
def ljust(self, width, *args):
1600
return self.__class__(self.data.ljust(width, *args))
1603
return self.__class__(self.data.lower())
1605
def lstrip(self, chars=None):
1606
return self.__class__(self.data.lstrip(chars))
1608
maketrans = str.maketrans
1610
def partition(self, sep):
1611
return self.data.partition(sep)
1613
def replace(self, old, new, maxsplit=-1):
1614
if isinstance(old, UserString):
1616
if isinstance(new, UserString):
1618
return self.__class__(self.data.replace(old, new, maxsplit))
1620
def rfind(self, sub, start=0, end=_sys.maxsize):
1621
if isinstance(sub, UserString):
1623
return self.data.rfind(sub, start, end)
1625
def rindex(self, sub, start=0, end=_sys.maxsize):
1626
if isinstance(sub, UserString):
1628
return self.data.rindex(sub, start, end)
1630
def rjust(self, width, *args):
1631
return self.__class__(self.data.rjust(width, *args))
1633
def rpartition(self, sep):
1634
return self.data.rpartition(sep)
1636
def rstrip(self, chars=None):
1637
return self.__class__(self.data.rstrip(chars))
1639
def split(self, sep=None, maxsplit=-1):
1640
return self.data.split(sep, maxsplit)
1642
def rsplit(self, sep=None, maxsplit=-1):
1643
return self.data.rsplit(sep, maxsplit)
1645
def splitlines(self, keepends=False):
1646
return self.data.splitlines(keepends)
1648
def startswith(self, prefix, start=0, end=_sys.maxsize):
1649
return self.data.startswith(prefix, start, end)
1651
def strip(self, chars=None):
1652
return self.__class__(self.data.strip(chars))
1655
return self.__class__(self.data.swapcase())
1658
return self.__class__(self.data.title())
1660
def translate(self, *args):
1661
return self.__class__(self.data.translate(*args))
1664
return self.__class__(self.data.upper())
1666
def zfill(self, width):
1667
return self.__class__(self.data.zfill(width))