<s> from operator import itemgetter <EOL> from heapq import nlargest <EOL> from itertools import repeat , ifilter <EOL> class Counter ( dict ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , iterable = None , ** kwds ) : <EOL> '''<STR_LIT>''' <EOL> self . update ( iterable , ** kwds ) <EOL> def __missing__ ( self , key ) : <EOL> return <NUM_LIT:0> <EOL> def most_common ( self , n = None ) : <EOL> '''<STR_LIT>''' <EOL> if n is None : <EOL> return sorted ( self . iteritems ( ) , key = itemgetter ( <NUM_LIT:1> ) , reverse = True ) <EOL> return nlargest ( n , self . iteritems ( ) , key = itemgetter ( <NUM_LIT:1> ) ) <EOL> def elements ( self ) : <EOL> '''<STR_LIT>''' <EOL> for elem , count in self . iteritems ( ) : <EOL> for _ in repeat ( None , count ) : <EOL> yield elem <EOL> @ classmethod <EOL> def fromkeys ( cls , iterable , v = None ) : <EOL> raise NotImplementedError ( <EOL> '<STR_LIT>' ) <EOL> def update ( self , iterable = None , ** kwds ) : <EOL> '''<STR_LIT>''' <EOL> if iterable is not None : <EOL> if hasattr ( iterable , '<STR_LIT>' ) : <EOL> if self : <EOL> self_get = self . get <EOL> for elem , count in iterable . iteritems ( ) : <EOL> self [ elem ] = self_get ( elem , <NUM_LIT:0> ) + count <EOL> else : <EOL> dict . update ( self , iterable ) <EOL> else : <EOL> self_get = self . get <EOL> for elem in iterable : <EOL> self [ elem ] = self_get ( elem , <NUM_LIT:0> ) + <NUM_LIT:1> <EOL> if kwds : <EOL> self . update ( kwds ) <EOL> def copy ( self ) : <EOL> '<STR_LIT>' <EOL> return Counter ( self ) <EOL> def __delitem__ ( self , elem ) : <EOL> '<STR_LIT>' <EOL> if elem in self : <EOL> dict . __delitem__ ( self , elem ) <EOL> def __repr__ ( self ) : <EOL> if not self : <EOL> return '<STR_LIT>' % self . __class__ . __name__ <EOL> items = '<STR_LIT:U+002CU+0020>' . join ( map ( '<STR_LIT>' . __mod__ , self . most_common ( ) ) ) <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , items ) <EOL> def __add__ ( self , other ) : <EOL> '''<STR_LIT>''' <EOL> if not isinstance ( other , Counter ) : <EOL> return NotImplemented <EOL> result = Counter ( ) <EOL> for elem in set ( self ) | set ( other ) : <EOL> newcount = self [ elem ] + other [ elem ] <EOL> if newcount > <NUM_LIT:0> : <EOL> result [ elem ] = newcount <EOL> return result <EOL> def __sub__ ( self , other ) : <EOL> '''<STR_LIT>''' <EOL> if not isinstance ( other , Counter ) : <EOL> return NotImplemented <EOL> result = Counter ( ) <EOL> for elem in set ( self ) | set ( other ) : <EOL> newcount = self [ elem ] - other [ elem ] <EOL> if newcount > <NUM_LIT:0> : <EOL> result [ elem ] = newcount <EOL> return result <EOL> def __or__ ( self , other ) : <EOL> '''<STR_LIT>''' <EOL> if not isinstance ( other , Counter ) : <EOL> return NotImplemented <EOL> _max = max <EOL> result = Counter ( ) <EOL> for elem in set ( self ) | set ( other ) : <EOL> newcount = _max ( self [ elem ] , other [ elem ] ) <EOL> if newcount > <NUM_LIT:0> : <EOL> result [ elem ] = newcount <EOL> return result <EOL> def __and__ ( self , other ) : <EOL> '''<STR_LIT>''' <EOL> if not isinstance ( other , Counter ) : <EOL> return NotImplemented <EOL> _min = min <EOL> result = Counter ( ) <EOL> if len ( self ) < len ( other ) : <EOL> self , other = other , self <EOL> for elem in ifilter ( self . __contains__ , other ) : <EOL> newcount = _min ( self [ elem ] , other [ elem ] ) <EOL> if newcount > <NUM_LIT:0> : <EOL> result [ elem ] = newcount <EOL> return result </s>
