python merge set of fronzensets into one set
Asked Answered
C

2

10

I am trying to merge sets defined in a set and this is what I have now

a = frozenset([1,3,4])
b = frozenset([1,2,3,4,5])
s = set()
s.add(a)
s.add(b)
merged = set(itertools.chain.from_iterable(s))

In practice, s may contain many frozensets. Is there better ways to do it? It feels like a reduce case, but

from functools import reduce
merged = reduce(|, s)

doesn't work.

Also

merged = reduce(set.add, s)

doesn't work because the elements of s are frozensets.

Conscience answered 9/2, 2017 at 20:16 Comment(1)
| as a standalone function is known as operator.or_Seymour
E
15

If you have more than two frozensets, create a container (e.g., list) of them and apply a union:

listoffrozensets = [a,b,...]
frozenset().union(*listoffrozensets)
Euthenics answered 9/2, 2017 at 20:22 Comment(5)
Doesn't make a difference, really, but just use the method directly from the class without instantiating a useless instance: frozenset.unionTova
I would say this is the "correct" way of doing this. reduce is likely less efficient. Anyway, in Python, reduce is not encouraged. This is the reason it was removed form the built-ins namespace in python 3.Tova
@Tova True, union is about 20% faster than reduce, at least as reported by my %timeit.Euthenics
I just hit into a problem when listoffrozensets=[], then I got error. But frozenset().union(*[]) still works.Conscience
@Conscience Good point! frozenset().union(*listoffrozensets) works, too.Euthenics
T
9

You can use reduce, just use the appropriate function:

>>> from functools import reduce
>>> frozenset.union
<method 'union' of 'frozenset' objects>
>>> reduce(frozenset.union, [a,b])
frozenset({1, 2, 3, 4, 5})
>>>

You were on the right track with |, but | is an operator in Python, and can't be substituted for a function. But when you want to do that, import the operator!

>>> import operator
>>> reduce(operator.or_, [a,b])
frozenset({1, 2, 3, 4, 5})
Tova answered 9/2, 2017 at 20:20 Comment(1)
Note you'll need e.g. frozenset[int].union to avoid Type of "union" is partially unknown if you're typingRaising

© 2022 - 2024 — McMap. All rights reserved.