# compact set of integers
import math
class CompactSet:
def __init__(self, numbers = None, bits = None):
self.bits = 0
if numbers:
for n in numbers:
self.add(n)
elif bits:
self.bits = bits
def add(self, n):
self.bits |= 1 << n
def remove(self, n):
self.bits &= ~(1 << n)
def clear(self):
self.bits = 0
def union(self, other):
return CompactSet(bits = self.bits | other.bits)
__or__ = union
def intersection(self, other):
return CompactSet(bits = self.bits & other.bits)
__and__ = intersection
def difference(self, other):
return CompactSet(bits = self.bits & ~other.bits)
__sub__ = difference
def union_update(self, other):
self.bits |= other.bits
def intersection_update(self, other):
self.bits &= other.bits
def difference_update(self, other):
self.bits &= ~other.bits
def numbers(self):
return list(iter(self))
def isdisjoint(self, other):
return ((self & other).bits == 0)
def __eq__(self, other):
return (self.bits == other.bits)
def __ne__(self, other):
return not (self == other)
def issubset(self, other):
return (self.union(other) == other)
__le__ = issubset
def issuperset(self, other):
return (other <= self)
__ge__ = issuperset
def __lt__(self, other):
return (self <= other and self != other)
def __gt__(self, other):
return (other < self)
def __len__(self):
bits = self.bits
count = 0
while bits:
bits &= bits - 1
count += 1
return count
def __contains__(self, n):
return (self.bits & (1 << n) == 1 << n)
def __iter__(self):
if self.bits == 0:
raise StopIteration
for n in range(int(math.log(self.bits, 2)) + 1):
if n in self:
yield n
def __repr__(self):
return ''.join(["CompactSet(", str(self.numbers()), ")"])
if __name__ == '__main__':
import sys
s = set(range(10000))
cs = CompactSet(range(10000))
print 'Size of set(range(10000)) is ', sys.getsizeof(s) # note: this is actually underestimated
print 'Size of CompactSet(range(10000)) is ', sys.getsizeof(cs.bits)
Diff to Previous Revision
--- revision 1 2011-04-17 01:37:22
+++ revision 2 2011-04-17 16:21:02
@@ -100,5 +100,5 @@
import sys
s = set(range(10000))
cs = CompactSet(range(10000))
- print 'Size of set(range(10000)) is ', sys.getsizeof(s)
- print 'Size of CompactSet(range(10000)) is ', sys.getsizeof(cs)
+ print 'Size of set(range(10000)) is ', sys.getsizeof(s) # note: this is actually underestimated
+ print 'Size of CompactSet(range(10000)) is ', sys.getsizeof(cs.bits)