Simple Python implementation of bag/multiset

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MRAB

    Simple Python implementation of bag/multiset

    While another thread is talking about an ordered dict, I thought I'd
    try a simple implementation of a bag/multiset in Python. Comments/
    suggestions welcome, etc.

    class bag(object):
    def __add__(self, other):
    result = self.copy()
    for item, count in other.iteritems ():
    result._items[item] = result._items.g et(item, 0) + count
    return result
    def __and__(self, other):
    result = bag()
    for item, count in other.iteritems ():
    new_count = min(self._items .get(item, 0), count)
    if new_count 0:
    result._items[item] = new_count
    return result
    def __contains__(se lf, item):
    return item in self._items
    def __eq__(self, other):
    return self._items == other._items
    def __getitem__(sel f, item):
    return self._items[item]
    def __iadd__(self, other):
    self._items = self.__add__(ot her)._items
    return self
    def __iand__(self, other):
    self._items = self.__and__(ot her)._items
    return self
    def __init__(self, iterable=None):
    self._items = {}
    if iterable is not None:
    for item in iterable:
    self._items[item] = self._items.get (item, 0) + 1
    def __ior__(self, other):
    self._items = self.__or__(oth er)._items
    return self
    def __isub__(self, other):
    self._items = self.__sub__(ot her)._items
    return self
    def __iter__(self):
    for item, count in self.iteritems( ):
    for counter in xrange(count):
    yield item
    def __ixor__(self, other):
    self._items = self.__xor__(ot her)._items
    return self
    def __len__(self):
    return sum(self._items .itervalues())
    def __ne__(self, other):
    return self._items != other._items
    def __or__(self, other):
    result = self.copy()
    for item, count in other.iteritems ():
    result._items[item] = max(result._ite ms.get(item, 0),
    count)
    return result
    def __repr__(self):
    result = []
    for item, count in self.iteritems( ):
    result += [repr(item)] * count
    return 'bag([%s])' % ', '.join(result)
    def __setitem__(sel f, item, count):
    if not isinstance(coun t, int) or count < 0:
    raise ValueError
    if count 0:
    self._items[item] = count
    elif item in self._items:
    del self._items[item]
    def __sub__(self, other):
    result = bag()
    for item, count in self.iteritems( ):
    new_count = count - other._items.ge t(item, 0)
    if new_count 0:
    result._items[item] = new_count
    return result
    def __xor__(self, other):
    result = self.copy()
    for item, count in other.iteritems ():
    new_count = abs(result._ite ms.get(item, 0) - count)
    if new_count 0:
    result._items[item] = new_count
    elif item in result._item:
    del result._items[item]
    return result
    def add(self, item):
    self._items[item] = self._items.get (item, 0) + 1
    def discard(self, item):
    new_count = self._items.get (item, 0) - 1
    if new_count 0:
    self._items[item] = new_count
    elif new_count == 0:
    del self._items[item]
    def clear(self):
    self._items = {}
    def copy(self):
    result = bag()
    result._items = self._items.cop y()
    return result
    def difference(self , other):
    return self.__sub__(ot her)
    def difference_upda te(self, other):
    self._items = self.__sub__(ot her)._items
    def get(self, item, default=0):
    return self._items.get (item, default)
    def intersection(se lf, other):
    return self.__and__(ot her)
    def intersection_up date(self, other):
    self.__iand__(o ther)
    def items(self):
    return self._items.ite ms()
    def iteritems(self) :
    return self._items.ite ritems()
    def iterkeys(self):
    return self._items.ite rkeys()
    def itervalues(self ):
    return self._items.ite rvalues()
    def keys(self):
    return self._items.key s()
    def pop(self):
    item = self._items.key s()[0]
    self._items[item] -= 1
    if self._items[item] == 0:
    del self._items[item]
    return item
    def remove(self, item):
    new_count = self._items[item] - 1
    if new_count 0:
    self._items[item] = new_count
    else:
    del self._items[item]
    def symmetric_diffe rence(self, other):
    return self.__xor__(ot her)
    def symmetric_diffe rence_update(se lf, other):
    self.__ixor__(o ther)
    def union(self, other):
    return self.__or__(oth er)
    def update(self, other):
    self.__ior__(ot her)
    def values(self):
    return self._items.val ues()
Working...