Reputation: 41
I want the index of items from following list of lists which have overlapping elements.
slist = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [7, 8, 9, 10]]
Output should be like:
[0,1,2] and [3]
I tried the following but it gives me pairs of values from which it is difficult to segregate values as I expect
for ((i,a),(j,b)) in itertools.combinations(enumerate(slist),2):
if len(a.intersection(b)) > 0:
print("overlapping",i,j)
else:
print("non overlapping",i,j)
Output:
('non overlapping', 0, 1)
('non overlapping', 0, 2)
('overlapping', 0, 3)
('overlapping', 1, 2)
('non overlapping', 1, 3)
('non overlapping', 2, 3)
Upvotes: 3
Views: 238
Reputation: 5500
You can try the following:
intersection
between two set
.itertools.combinations
as in the question.Here's the code:
import itertools
slist = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [7, 8, 9, 10]]
# Dictionary to keep overlapping index
dict_ = {i: [i] for i in range(len(slist))}
# Iterate all combination
for combo in itertools.combinations([i for i in range(len(slist))], 2):
sublist_1 = slist[combo[0]]
sublist_2 = slist[combo[1]]
# Check if they overlap
if len(set(sublist_1).intersection(set(sublist_2))) > 0:
# Save index
dict_[combo[0]].append(combo[1])
dict_[combo[1]].append(combo[0])
print(dict_)
# {0: [0, 1, 2], 1: [1, 0, 2], 2: [2, 0, 1], 3: [3]}
# Order each sublist in list of index to then remove duplicates
list_ = [set(sub) for sub in (list(dict_.values()))]
print([list(i) for i in set(map(tuple, list_))])
# [[0, 1, 2], [3]]
Upvotes: 1
Reputation: 27515
You can do this using a list comprehension:
>>> slist = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [7, 8, 9, 10]]
>>> sets = tuple(map(set, slist))
>>> list(map(list, {tuple(i for i, _s in enumerate(sets) if s & _s) for s in sets}))
[[0, 1, 2], [3]]
If it makes it more readable/understandable I’m only using map to make the tuples into lists again. You need to use tuples as lists and sets are unhashable. If you don’t map list then it’s more readable but it results in a list of tuples.
list({tuple(i for i, _s in enumerate(sets) if s & _s) for s in sets}))
Upvotes: 4