]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Lib/collections.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / collections.py
1 __all__ = ['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict']
2 # For bootstrapping reasons, the collection ABCs are defined in _abcoll.py.
3 # They should however be considered an integral part of collections.py.
4 from _abcoll import *
5 import _abcoll
6 __all__ += _abcoll.__all__
7
8 from _collections import deque, defaultdict
9 from operator import itemgetter as _itemgetter
10 from keyword import iskeyword as _iskeyword
11 import sys as _sys
12 import heapq as _heapq
13 from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
14
15 try:
16 from thread import get_ident as _get_ident
17 except ImportError:
18 from dummy_thread import get_ident as _get_ident
19
20
21 ################################################################################
22 ### OrderedDict
23 ################################################################################
24
25 class OrderedDict(dict):
26 'Dictionary that remembers insertion order'
27 # An inherited dict maps keys to values.
28 # The inherited dict provides __getitem__, __len__, __contains__, and get.
29 # The remaining methods are order-aware.
30 # Big-O running times for all methods are the same as regular dictionaries.
31
32 # The internal self.__map dict maps keys to links in a doubly linked list.
33 # The circular doubly linked list starts and ends with a sentinel element.
34 # The sentinel element never gets deleted (this simplifies the algorithm).
35 # Each link is stored as a list of length three: [PREV, NEXT, KEY].
36
37 def __init__(self, *args, **kwds):
38 '''Initialize an ordered dictionary. The signature is the same as
39 regular dictionaries, but keyword arguments are not recommended because
40 their insertion order is arbitrary.
41
42 '''
43 if len(args) > 1:
44 raise TypeError('expected at most 1 arguments, got %d' % len(args))
45 try:
46 self.__root
47 except AttributeError:
48 self.__root = root = [] # sentinel node
49 root[:] = [root, root, None]
50 self.__map = {}
51 self.__update(*args, **kwds)
52
53 def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
54 'od.__setitem__(i, y) <==> od[i]=y'
55 # Setting a new item creates a new link at the end of the linked list,
56 # and the inherited dictionary is updated with the new key/value pair.
57 if key not in self:
58 root = self.__root
59 last = root[PREV]
60 last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
61 dict_setitem(self, key, value)
62
63 def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
64 'od.__delitem__(y) <==> del od[y]'
65 # Deleting an existing item uses self.__map to find the link which gets
66 # removed by updating the links in the predecessor and successor nodes.
67 dict_delitem(self, key)
68 link_prev, link_next, key = self.__map.pop(key)
69 link_prev[NEXT] = link_next
70 link_next[PREV] = link_prev
71
72 def __iter__(self):
73 'od.__iter__() <==> iter(od)'
74 # Traverse the linked list in order.
75 NEXT, KEY = 1, 2
76 root = self.__root
77 curr = root[NEXT]
78 while curr is not root:
79 yield curr[KEY]
80 curr = curr[NEXT]
81
82 def __reversed__(self):
83 'od.__reversed__() <==> reversed(od)'
84 # Traverse the linked list in reverse order.
85 PREV, KEY = 0, 2
86 root = self.__root
87 curr = root[PREV]
88 while curr is not root:
89 yield curr[KEY]
90 curr = curr[PREV]
91
92 def clear(self):
93 'od.clear() -> None. Remove all items from od.'
94 for node in self.__map.itervalues():
95 del node[:]
96 root = self.__root
97 root[:] = [root, root, None]
98 self.__map.clear()
99 dict.clear(self)
100
101 # -- the following methods do not depend on the internal structure --
102
103 def keys(self):
104 'od.keys() -> list of keys in od'
105 return list(self)
106
107 def values(self):
108 'od.values() -> list of values in od'
109 return [self[key] for key in self]
110
111 def items(self):
112 'od.items() -> list of (key, value) pairs in od'
113 return [(key, self[key]) for key in self]
114
115 def iterkeys(self):
116 'od.iterkeys() -> an iterator over the keys in od'
117 return iter(self)
118
119 def itervalues(self):
120 'od.itervalues -> an iterator over the values in od'
121 for k in self:
122 yield self[k]
123
124 def iteritems(self):
125 'od.iteritems -> an iterator over the (key, value) pairs in od'
126 for k in self:
127 yield (k, self[k])
128
129 update = MutableMapping.update
130
131 __update = update # let subclasses override update without breaking __init__
132
133 __marker = object()
134
135 def pop(self, key, default=__marker):
136 '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
137 value. If key is not found, d is returned if given, otherwise KeyError
138 is raised.
139
140 '''
141 if key in self:
142 result = self[key]
143 del self[key]
144 return result
145 if default is self.__marker:
146 raise KeyError(key)
147 return default
148
149 def setdefault(self, key, default=None):
150 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
151 if key in self:
152 return self[key]
153 self[key] = default
154 return default
155
156 def popitem(self, last=True):
157 '''od.popitem() -> (k, v), return and remove a (key, value) pair.
158 Pairs are returned in LIFO order if last is true or FIFO order if false.
159
160 '''
161 if not self:
162 raise KeyError('dictionary is empty')
163 key = next(reversed(self) if last else iter(self))
164 value = self.pop(key)
165 return key, value
166
167 def __repr__(self, _repr_running={}):
168 'od.__repr__() <==> repr(od)'
169 call_key = id(self), _get_ident()
170 if call_key in _repr_running:
171 return '...'
172 _repr_running[call_key] = 1
173 try:
174 if not self:
175 return '%s()' % (self.__class__.__name__,)
176 return '%s(%r)' % (self.__class__.__name__, self.items())
177 finally:
178 del _repr_running[call_key]
179
180 def __reduce__(self):
181 'Return state information for pickling'
182 items = [[k, self[k]] for k in self]
183 inst_dict = vars(self).copy()
184 for k in vars(OrderedDict()):
185 inst_dict.pop(k, None)
186 if inst_dict:
187 return (self.__class__, (items,), inst_dict)
188 return self.__class__, (items,)
189
190 def copy(self):
191 'od.copy() -> a shallow copy of od'
192 return self.__class__(self)
193
194 @classmethod
195 def fromkeys(cls, iterable, value=None):
196 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
197 If not specified, the value defaults to None.
198
199 '''
200 self = cls()
201 for key in iterable:
202 self[key] = value
203 return self
204
205 def __eq__(self, other):
206 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
207 while comparison to a regular mapping is order-insensitive.
208
209 '''
210 if isinstance(other, OrderedDict):
211 return len(self)==len(other) and self.items() == other.items()
212 return dict.__eq__(self, other)
213
214 def __ne__(self, other):
215 'od.__ne__(y) <==> od!=y'
216 return not self == other
217
218 # -- the following methods support python 3.x style dictionary views --
219
220 def viewkeys(self):
221 "od.viewkeys() -> a set-like object providing a view on od's keys"
222 return KeysView(self)
223
224 def viewvalues(self):
225 "od.viewvalues() -> an object providing a view on od's values"
226 return ValuesView(self)
227
228 def viewitems(self):
229 "od.viewitems() -> a set-like object providing a view on od's items"
230 return ItemsView(self)
231
232
233 ################################################################################
234 ### namedtuple
235 ################################################################################
236
237 def namedtuple(typename, field_names, verbose=False, rename=False):
238 """Returns a new subclass of tuple with named fields.
239
240 >>> Point = namedtuple('Point', 'x y')
241 >>> Point.__doc__ # docstring for the new class
242 'Point(x, y)'
243 >>> p = Point(11, y=22) # instantiate with positional args or keywords
244 >>> p[0] + p[1] # indexable like a plain tuple
245 33
246 >>> x, y = p # unpack like a regular tuple
247 >>> x, y
248 (11, 22)
249 >>> p.x + p.y # fields also accessable by name
250 33
251 >>> d = p._asdict() # convert to a dictionary
252 >>> d['x']
253 11
254 >>> Point(**d) # convert from a dictionary
255 Point(x=11, y=22)
256 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
257 Point(x=100, y=22)
258
259 """
260
261 # Parse and validate the field names. Validation serves two purposes,
262 # generating informative error messages and preventing template injection attacks.
263 if isinstance(field_names, basestring):
264 field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
265 field_names = tuple(map(str, field_names))
266 if rename:
267 names = list(field_names)
268 seen = set()
269 for i, name in enumerate(names):
270 if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
271 or not name or name[0].isdigit() or name.startswith('_')
272 or name in seen):
273 names[i] = '_%d' % i
274 seen.add(name)
275 field_names = tuple(names)
276 for name in (typename,) + field_names:
277 if not all(c.isalnum() or c=='_' for c in name):
278 raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
279 if _iskeyword(name):
280 raise ValueError('Type names and field names cannot be a keyword: %r' % name)
281 if name[0].isdigit():
282 raise ValueError('Type names and field names cannot start with a number: %r' % name)
283 seen_names = set()
284 for name in field_names:
285 if name.startswith('_') and not rename:
286 raise ValueError('Field names cannot start with an underscore: %r' % name)
287 if name in seen_names:
288 raise ValueError('Encountered duplicate field name: %r' % name)
289 seen_names.add(name)
290
291 # Create and fill-in the class template
292 numfields = len(field_names)
293 argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
294 reprtxt = ', '.join('%s=%%r' % name for name in field_names)
295 template = '''class %(typename)s(tuple):
296 '%(typename)s(%(argtxt)s)' \n
297 __slots__ = () \n
298 _fields = %(field_names)r \n
299 def __new__(_cls, %(argtxt)s):
300 'Create new instance of %(typename)s(%(argtxt)s)'
301 return _tuple.__new__(_cls, (%(argtxt)s)) \n
302 @classmethod
303 def _make(cls, iterable, new=tuple.__new__, len=len):
304 'Make a new %(typename)s object from a sequence or iterable'
305 result = new(cls, iterable)
306 if len(result) != %(numfields)d:
307 raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
308 return result \n
309 def __repr__(self):
310 'Return a nicely formatted representation string'
311 return '%(typename)s(%(reprtxt)s)' %% self \n
312 def _asdict(self):
313 'Return a new OrderedDict which maps field names to their values'
314 return OrderedDict(zip(self._fields, self)) \n
315 def _replace(_self, **kwds):
316 'Return a new %(typename)s object replacing specified fields with new values'
317 result = _self._make(map(kwds.pop, %(field_names)r, _self))
318 if kwds:
319 raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
320 return result \n
321 def __getnewargs__(self):
322 'Return self as a plain tuple. Used by copy and pickle.'
323 return tuple(self) \n\n''' % locals()
324 for i, name in enumerate(field_names):
325 template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i)
326 if verbose:
327 print template
328
329 # Execute the template string in a temporary namespace and
330 # support tracing utilities by setting a value for frame.f_globals['__name__']
331 namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
332 OrderedDict=OrderedDict, _property=property, _tuple=tuple)
333 try:
334 exec template in namespace
335 except SyntaxError, e:
336 raise SyntaxError(e.message + ':\n' + template)
337 result = namespace[typename]
338
339 # For pickling to work, the __module__ variable needs to be set to the frame
340 # where the named tuple is created. Bypass this step in enviroments where
341 # sys._getframe is not defined (Jython for example) or sys._getframe is not
342 # defined for arguments greater than 0 (IronPython).
343 try:
344 result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
345 except (AttributeError, ValueError):
346 pass
347
348 return result
349
350
351 ########################################################################
352 ### Counter
353 ########################################################################
354
355 class Counter(dict):
356 '''Dict subclass for counting hashable items. Sometimes called a bag
357 or multiset. Elements are stored as dictionary keys and their counts
358 are stored as dictionary values.
359
360 >>> c = Counter('abcdeabcdabcaba') # count elements from a string
361
362 >>> c.most_common(3) # three most common elements
363 [('a', 5), ('b', 4), ('c', 3)]
364 >>> sorted(c) # list all unique elements
365 ['a', 'b', 'c', 'd', 'e']
366 >>> ''.join(sorted(c.elements())) # list elements with repetitions
367 'aaaaabbbbcccdde'
368 >>> sum(c.values()) # total of all counts
369 15
370
371 >>> c['a'] # count of letter 'a'
372 5
373 >>> for elem in 'shazam': # update counts from an iterable
374 ... c[elem] += 1 # by adding 1 to each element's count
375 >>> c['a'] # now there are seven 'a'
376 7
377 >>> del c['b'] # remove all 'b'
378 >>> c['b'] # now there are zero 'b'
379 0
380
381 >>> d = Counter('simsalabim') # make another counter
382 >>> c.update(d) # add in the second counter
383 >>> c['a'] # now there are nine 'a'
384 9
385
386 >>> c.clear() # empty the counter
387 >>> c
388 Counter()
389
390 Note: If a count is set to zero or reduced to zero, it will remain
391 in the counter until the entry is deleted or the counter is cleared:
392
393 >>> c = Counter('aaabbc')
394 >>> c['b'] -= 2 # reduce the count of 'b' by two
395 >>> c.most_common() # 'b' is still in, but its count is zero
396 [('a', 3), ('c', 1), ('b', 0)]
397
398 '''
399 # References:
400 # http://en.wikipedia.org/wiki/Multiset
401 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
402 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
403 # http://code.activestate.com/recipes/259174/
404 # Knuth, TAOCP Vol. II section 4.6.3
405
406 def __init__(self, iterable=None, **kwds):
407 '''Create a new, empty Counter object. And if given, count elements
408 from an input iterable. Or, initialize the count from another mapping
409 of elements to their counts.
410
411 >>> c = Counter() # a new, empty counter
412 >>> c = Counter('gallahad') # a new counter from an iterable
413 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
414 >>> c = Counter(a=4, b=2) # a new counter from keyword args
415
416 '''
417 super(Counter, self).__init__()
418 self.update(iterable, **kwds)
419
420 def __missing__(self, key):
421 'The count of elements not in the Counter is zero.'
422 # Needed so that self[missing_item] does not raise KeyError
423 return 0
424
425 def most_common(self, n=None):
426 '''List the n most common elements and their counts from the most
427 common to the least. If n is None, then list all element counts.
428
429 >>> Counter('abcdeabcdabcaba').most_common(3)
430 [('a', 5), ('b', 4), ('c', 3)]
431
432 '''
433 # Emulate Bag.sortedByCount from Smalltalk
434 if n is None:
435 return sorted(self.iteritems(), key=_itemgetter(1), reverse=True)
436 return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1))
437
438 def elements(self):
439 '''Iterator over elements repeating each as many times as its count.
440
441 >>> c = Counter('ABCABC')
442 >>> sorted(c.elements())
443 ['A', 'A', 'B', 'B', 'C', 'C']
444
445 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
446 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
447 >>> product = 1
448 >>> for factor in prime_factors.elements(): # loop over factors
449 ... product *= factor # and multiply them
450 >>> product
451 1836
452
453 Note, if an element's count has been set to zero or is a negative
454 number, elements() will ignore it.
455
456 '''
457 # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
458 return _chain.from_iterable(_starmap(_repeat, self.iteritems()))
459
460 # Override dict methods where necessary
461
462 @classmethod
463 def fromkeys(cls, iterable, v=None):
464 # There is no equivalent method for counters because setting v=1
465 # means that no element can have a count greater than one.
466 raise NotImplementedError(
467 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
468
469 def update(self, iterable=None, **kwds):
470 '''Like dict.update() but add counts instead of replacing them.
471
472 Source can be an iterable, a dictionary, or another Counter instance.
473
474 >>> c = Counter('which')
475 >>> c.update('witch') # add elements from another iterable
476 >>> d = Counter('watch')
477 >>> c.update(d) # add elements from another counter
478 >>> c['h'] # four 'h' in which, witch, and watch
479 4
480
481 '''
482 # The regular dict.update() operation makes no sense here because the
483 # replace behavior results in the some of original untouched counts
484 # being mixed-in with all of the other counts for a mismash that
485 # doesn't have a straight-forward interpretation in most counting
486 # contexts. Instead, we implement straight-addition. Both the inputs
487 # and outputs are allowed to contain zero and negative counts.
488
489 if iterable is not None:
490 if isinstance(iterable, Mapping):
491 if self:
492 self_get = self.get
493 for elem, count in iterable.iteritems():
494 self[elem] = self_get(elem, 0) + count
495 else:
496 super(Counter, self).update(iterable) # fast path when counter is empty
497 else:
498 self_get = self.get
499 for elem in iterable:
500 self[elem] = self_get(elem, 0) + 1
501 if kwds:
502 self.update(kwds)
503
504 def subtract(self, iterable=None, **kwds):
505 '''Like dict.update() but subtracts counts instead of replacing them.
506 Counts can be reduced below zero. Both the inputs and outputs are
507 allowed to contain zero and negative counts.
508
509 Source can be an iterable, a dictionary, or another Counter instance.
510
511 >>> c = Counter('which')
512 >>> c.subtract('witch') # subtract elements from another iterable
513 >>> c.subtract(Counter('watch')) # subtract elements from another counter
514 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
515 0
516 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
517 -1
518
519 '''
520 if iterable is not None:
521 self_get = self.get
522 if isinstance(iterable, Mapping):
523 for elem, count in iterable.items():
524 self[elem] = self_get(elem, 0) - count
525 else:
526 for elem in iterable:
527 self[elem] = self_get(elem, 0) - 1
528 if kwds:
529 self.subtract(kwds)
530
531 def copy(self):
532 'Return a shallow copy.'
533 return self.__class__(self)
534
535 def __reduce__(self):
536 return self.__class__, (dict(self),)
537
538 def __delitem__(self, elem):
539 'Like dict.__delitem__() but does not raise KeyError for missing values.'
540 if elem in self:
541 super(Counter, self).__delitem__(elem)
542
543 def __repr__(self):
544 if not self:
545 return '%s()' % self.__class__.__name__
546 items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
547 return '%s({%s})' % (self.__class__.__name__, items)
548
549 # Multiset-style mathematical operations discussed in:
550 # Knuth TAOCP Volume II section 4.6.3 exercise 19
551 # and at http://en.wikipedia.org/wiki/Multiset
552 #
553 # Outputs guaranteed to only include positive counts.
554 #
555 # To strip negative and zero counts, add-in an empty counter:
556 # c += Counter()
557
558 def __add__(self, other):
559 '''Add counts from two counters.
560
561 >>> Counter('abbb') + Counter('bcc')
562 Counter({'b': 4, 'c': 2, 'a': 1})
563
564 '''
565 if not isinstance(other, Counter):
566 return NotImplemented
567 result = Counter()
568 for elem, count in self.items():
569 newcount = count + other[elem]
570 if newcount > 0:
571 result[elem] = newcount
572 for elem, count in other.items():
573 if elem not in self and count > 0:
574 result[elem] = count
575 return result
576
577 def __sub__(self, other):
578 ''' Subtract count, but keep only results with positive counts.
579
580 >>> Counter('abbbc') - Counter('bccd')
581 Counter({'b': 2, 'a': 1})
582
583 '''
584 if not isinstance(other, Counter):
585 return NotImplemented
586 result = Counter()
587 for elem, count in self.items():
588 newcount = count - other[elem]
589 if newcount > 0:
590 result[elem] = newcount
591 for elem, count in other.items():
592 if elem not in self and count < 0:
593 result[elem] = 0 - count
594 return result
595
596 def __or__(self, other):
597 '''Union is the maximum of value in either of the input counters.
598
599 >>> Counter('abbb') | Counter('bcc')
600 Counter({'b': 3, 'c': 2, 'a': 1})
601
602 '''
603 if not isinstance(other, Counter):
604 return NotImplemented
605 result = Counter()
606 for elem, count in self.items():
607 other_count = other[elem]
608 newcount = other_count if count < other_count else count
609 if newcount > 0:
610 result[elem] = newcount
611 for elem, count in other.items():
612 if elem not in self and count > 0:
613 result[elem] = count
614 return result
615
616 def __and__(self, other):
617 ''' Intersection is the minimum of corresponding counts.
618
619 >>> Counter('abbb') & Counter('bcc')
620 Counter({'b': 1})
621
622 '''
623 if not isinstance(other, Counter):
624 return NotImplemented
625 result = Counter()
626 for elem, count in self.items():
627 other_count = other[elem]
628 newcount = count if count < other_count else other_count
629 if newcount > 0:
630 result[elem] = newcount
631 return result
632
633
634 if __name__ == '__main__':
635 # verify that instances can be pickled
636 from cPickle import loads, dumps
637 Point = namedtuple('Point', 'x, y', True)
638 p = Point(x=10, y=20)
639 assert p == loads(dumps(p))
640
641 # test and demonstrate ability to override methods
642 class Point(namedtuple('Point', 'x y')):
643 __slots__ = ()
644 @property
645 def hypot(self):
646 return (self.x ** 2 + self.y ** 2) ** 0.5
647 def __str__(self):
648 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
649
650 for p in Point(3, 4), Point(14, 5/7.):
651 print p
652
653 class Point(namedtuple('Point', 'x y')):
654 'Point class with optimized _make() and _replace() without error-checking'
655 __slots__ = ()
656 _make = classmethod(tuple.__new__)
657 def _replace(self, _map=map, **kwds):
658 return self._make(_map(kwds.get, ('x', 'y'), self))
659
660 print Point(11, 22)._replace(x=100)
661
662 Point3D = namedtuple('Point3D', Point._fields + ('z',))
663 print Point3D.__doc__
664
665 import doctest
666 TestResults = namedtuple('TestResults', 'failed attempted')
667 print TestResults(*doctest.testmod())