我想要以下具有重叠元素的列表中的项目的索引。
slist = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [7, 8, 9, 10]]
输出应类似于:
[0,1,2] and [3]
我尝试了以下方法,但是它给了我成对的值,很难像我期望的那样将值分开
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)
答案 0 :(得分:4)
您可以使用列表理解来做到这一点:
>>> 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]]
如果它使可读性更强/更易于理解,我只是在使用map将元组再次放入列表中。您需要使用元组,因为列表和集合不可散列。如果您不映射列表,则它更易读,但会生成一个元组列表。
list({tuple(i for i, _s in enumerate(sets) if s & _s) for s in sets}))
答案 1 :(得分:1)
您可以尝试以下操作:
intersection
之间使用set
。itertools.combinations
,如问题中所示。代码在这里:
import itertools
slist = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [7, 8, 9, 10]]
# Dictionnary 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]]