This recipe provides a subclass of set which implements __mul__ and __pow__ to support the computation of set products. When multiplying two sets together, a new set is produced with elements which are the inter-set pairs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import operator
class Set(set):
def __mul__(self, other):
if not isinstance(other, set):
return NotImplemented
return Set(self._join_elements(x, y) for x in self for y in other)
def __pow__(self, amount):
if not isinstance(amount, int):
return NotImplemented
return reduce(operator.mul, (self for _ in xrange(amount)))
def _join_elements(self, x, y):
if not isinstance(x, tuple):
x = (x,)
if not isinstance(y, tuple):
y = (y,)
return x + y
def __repr__(self):
s = set.__repr__(self)
return '%s(%s' % (self.__class__.__name__, s.split('(', 1)[1])
def main():
# binary numbers of 3 bits
s = Set([0, 1])
print s ** 3
if __name__ == '__main__':
main()
|
Products are a useful thing to compute when working with sets. For example, the set of binary numbers of size n can be computed as {0, 1} ** n.
Nice recipe!
Note that starting with Python 2.6, you can achieve the same thing using itertools.product:
Hi Gabriel,
Thanks for the comment.
itertools.product
is great, but it doesn't quite achieve the same thing; this recipe joins tuples if they're there:But the main thing about this recipe is the notation that it allows for (
x * y
). Operator overloading is a great language feature.