Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 33 lines
 ``` 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)) 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. Gabriel Genellina 11 years, 7 months ago

Nice recipe!

Note that starting with Python 2.6, you can achieve the same thing using itertools.product:

``````py> s = Set(['a','b'])
py> t = Set([1,2,3])
py> s*t
Set([('a', 1), ('b', 2), ('b', 3), ('b', 1), ('a', 3), ('a', 2)])

py> s = set(['a','b'])
py> t = set([1,2,3])
py> set(product(s,t))
set([('a', 1), ('b', 2), ('b', 3), ('b', 1), ('a', 3), ('a', 2)])
`````` Paul G (author) 11 years, 7 months ago

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:

``````>>> ab = Set(['a', 'b'])
>>> st = Set(['s', 't'])
>>> xy = Set(['x', 'y'])

>>> ab_st = ab * st
>>> ab_st * xy
Set([('a', 's', 'x'), ('a', 't', 'x'), ('a', 's', 'y'), ...])

>>> ab_st = product(ab, st)
>>> set(product(ab_st, xy))
set([(('b', 't'), 'y'), (('a', 's'), 'y'), (('b', 's'), 'x'), ...])
``````

But the main thing about this recipe is the notation that it allows for (`x * y`). Operator overloading is a great language feature. Created by Paul G on Mon, 12 Apr 2010 (MIT)