Reputation: 166
Let's say I got something like ((1, 2), (2, 3), (2, 3))
. As you can see, 2 is repeated across all of tuples in the tuple. I want something to return (2)
.
The real data set I'm working on is:
(
(2, 3, 5, 7, 9),
(2, 3, 4, 5, 7, 8, 10),
(2, 3, 4, 5, 6, 7, 9, 10),
(2, 3, 4, 5, 6, 7, 8, 9),
(2, 3, 4, 5, 6, 7, 8, 9, 10),
(2, 3, 4, 5, 6, 7, 8, 9, 10),
(2, 3, 4, 5, 6, 7, 8, 9, 10),
(2, 3, 4, 5, 6, 7, 8, 9, 10),
(2, 3, 4, 5, 6, 7, 8, 9, 10)
)
And I'm excepting it to return (2, 3, 5, 7)
.
I have already tried the following, but it returns an empty tuple for some reason.
a = ((1, 2), (2, 3), (2, 3))
print(tuple(filter(lambda x: all(x in i for i in a), a)))
There are three things that are important to me.
for
as possible, instead map
or filter
So basically, I want to do this functionally.
Upvotes: 1
Views: 241
Reputation: 7240
(*set.intersection(*map(set, t)),)
p.s. Looks like I have to add some words to avoid labeling the answer as low quality. But the idea seems quite obvious: create sets from tuples and get their intersection.
Update
It seems that we could do without reduce
or map
by creating a set or frozen set once and providing iterables to its intersection
method:
frozenset(t[0]).intersection(*t[1:])
Upvotes: 1
Reputation: 3243
Using Counter
from itertools import chain
from collections import Counter
a = ((2, 3, 5, 7, 9), (2, 3, 4, 5, 7, 8, 10), (2, 3, 4, 5, 6, 7, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10))
print([ele[0] for ele in Counter(chain(*a)).items() if ele[1]==len(a)])
Upvotes: 1
Reputation: 3288
A slightly different approach: Given:
from functools import reduce
a = ((1, 2), (2, 3), (2, 3))
def combo(a, b)
return a&b
reduce(combo, [set(x) for x in a])
Yields {2}
Upvotes: 1
Reputation: 96172
Here, using functools.reduce
, you can do something like:
reduce(frozenset.intersection, map(frozenset, data))
Upvotes: 2
Reputation: 92460
You are taking a group of tuples and returning a single different tuple. So filter
is not really what you want. If you are thinking about functional programming, this really seems like a problem for reduce
That might look like:
from functools import reduce
t = ((2, 3, 5, 7, 9), (2, 3, 4, 5, 7, 8, 10), (2, 3, 4, 5, 6, 7, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10), (2, 3, 4, 5, 6, 7, 8, 9, 10))
reduce(lambda res, curr: tuple(n for n in res if n in curr), t)
# (2, 3, 5, 7)
Here you just create a single tuple res
on each iteration, which contains values seen by all lists.
Upvotes: 2