Разделить вложенный список на группы с непересекающимися элементами - PullRequest
3 голосов
/ 17 июня 2020

У меня есть список, который выглядит следующим образом:

my_list = [[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 12]]

, и я хотел бы найти лучший способ разделить список на две группы, чтобы отдельные элементы в каждой группе не перекрывались. Например, в приведенном выше примере две группы будут

group1 = [[1, 2, 3, 4], [4, 5, 6, 7]]
group2 = [[9, 10, 11, 12]]

, и это потому, что 9, 10, 11, 12 никогда не появляются ни в одном из элементов group1.

Ответы [ 3 ]

4 голосов
/ 17 июня 2020

Подобно Объединить списки с общими элементами , способ go об этом может заключаться в определении графа из вложенного списка, принимая каждый подсписок как путь , и ищем подключенные компоненты :

import networkx as nx

my_list = [[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 12]]

G=nx.Graph()
for l in my_list:
    nx.add_path(G, l)
components = list(nx.connected_components(G))
# [{1, 2, 3, 4, 5, 6, 7}, {9, 10, 11, 12}]    

groups = []
for component in components:
    group = []
    for path in my_list:
        if component.issuperset(path):
            group.append(path)
    groups.append(group)

groups
# [[[1, 2, 3, 4], [4, 5, 6, 7]], [[9, 10, 11, 12]]]
0 голосов
/ 17 июня 2020

Это должно сработать:

my_list = [[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 12], [22, 17, 16, 15], [9, 88, 39, 58]]

group1 = []
group2 = []

def contains(list1, list2):
    for item in list1:
        if item in list2:
            return True
    return False

counter = 0
while counter < len(my_list):
    actualinnerlist = my_list[counter]
    actualmy_list = my_list[:counter] + my_list[counter+1:]
    print(f"\nactualinnerlist item: {actualinnerlist}")
    print(f"actualmy_list item: {actualmy_list}")

    for innerlist in actualmy_list:
        print(f"Actual Inner List: {actualmy_list}")
        print(f"Inner List: {innerlist}")
        if contains(actualinnerlist, innerlist):
            group1.append(actualinnerlist)
            counter += 1
            break
    else:
        group2.append(actualinnerlist)
        counter += 1

print (f"Group1: {group1}")
print (f"Group2: {group2}")

Он просто сравнивает списки, но срезает список в while l oop, чтобы не сравнивать с одним и тем же элементом.

0 голосов
/ 17 июня 2020

Это должно сработать:

my_list = [[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 12]]


grp1 = []
grp2 = []

for i in range(len(my_list)):
    j = i+1
    if my_list[i] not in grp1:
        for ele in my_list[i]:
            try:
                if ele in my_list[j]:
                    grp1.append(my_list[i])
                    grp1.append(my_list[j])
            except:
                pass
    else:
        continue

for lst in my_list:
    if lst not in grp1:
        grp2.append(lst)
    else:
        continue

print(grp1)
print(grp2)
...