views:

54

answers:

3

Suppose I have a list of sets and I want to get the union over all sets in that list. Is there any way to do this using a generator expression? In other words, how can I create the union over all sets in that list directly as a frozenset?

+5  A: 

Just use the .union() method.

>>> l = [set([1,2,3]), set([4,5,6]), set([1,4,9])]
>>> frozenset().union(*l)
frozenset([1, 2, 3, 4, 5, 6, 9])

This works for any iterable of iterables.

KennyTM
+3  A: 

Nested generator expression. But I think they are a bit cryptic, so the way KennyTM suggested may be clearer.

frozenset(some_item for some_set in some_sets for some_item in some_set)
delnan
+1 for cleverness
aaronasterling
+3  A: 

I assume that what you're trying to avoid is the intermediate creations of frozenset objects as you're building up the union?

Here's one way to do it. NOTE: this originally used itertools.chain() but, as Kenny's comment notes, the version below is slightly better:

import itertools

def mkunion(*args):
    return frozenset(itertools.chain.from_iterable(args))

Invoke like this:

a = set(['a','b','c'])
b = set(['a','e','f'])
c = mkunion(a,b)       # => frozenset(['a', 'c', 'b', 'e', 'f'])
Owen S.
Use `chain.from_iterable` if you're going to `.chain(*args)`.
KennyTM
@KennyTM: Good point, I've made the change.
Owen S.