CDspace
CDspace

Reputation: 2689

Run a function returning a set on a set, and get back a larger set

We can use list comprehensions on a list, and get back a list of each element run through a function. We can do the same thing with a set.

I'm looking to run each element of a set through a function, that could return another set, larger than the original input. Is this possible with comprehensions?

I could do something like this, but is there a one-liner for it?

ret = set()
q = { 1, 2, 3, 4 }
def doubleIt( t ):
    return { t, t**2 }

for w in q:
    ret.update( doubleIt( w ) )

ret
>> { 1, 2, 3, 4, 9, 16 }

The returning function will be much more complex, and could possibly return a set of sets, which I'll have to reduce further, so a one-liner would be very useful.

EDIT: Note that the returning function might also return a set. See in the example that running 2 through the function returns {2, 4} and running 4 through it returns {4, 16}, yet 4 only appears in the desired output once.

Upvotes: 0

Views: 1670

Answers (5)

Nir Alfasi
Nir Alfasi

Reputation: 53535

Two expressions yet, it's a one-liner which is not long:

q = { 1, 2, 3, 4 } # given
def f(x):
    return x * x
ret = q | set(f(x) for x in q)

In case f(x) returns a set:

reduce(lambda a, b: a | b, map(lambda a: f(a), q))

Upvotes: 2

Sneha
Sneha

Reputation: 140

One liner solution:

z=set(map(lambda x:x**2,q)).union(q)

Upvotes: 1

kchawla-pi
kchawla-pi

Reputation: 449

The best one-liner, IMO is this:

q = { 1, 2, 3, 4 }
l = set(elem **2 for elem in q).union(q)

Upvotes: 0

user2357112
user2357112

Reputation: 281330

Here's a short way to do it without comprehensions:

set().union(*map(doubleIt, q))

It calls doubleIt on every element of q and merges the resulting sets into one set with set().union.

If you want a comprehension, use a set comprehension with two for clauses:

ret = {new_elem for elem in q for new_elem in doubleIt(elem)}

This iterates over q, calls doubleIt on each element, and iterates over the sets returned by doubleIt, putting the elements of those sets in the new set. It's equivalent to

ret = set()
for elem in q:
    for new_elem in doubleIt(elem):
        ret.add(new_elem)

Upvotes: 2

Rahul K P
Rahul K P

Reputation: 16091

Using set.union + reduce + map

In [27]: reduce(set.union,map(doubleIt,q))
Out[27]: {1, 2, 3, 4, 9, 16}

Just apply map function will apply the function into all elements and that will return a list of set. Then combine the set.

Upvotes: 2

Related Questions