Python fusionner la liste multiple avec intersection [dupliquer]

possible Duplicate:

Python: fusion de liste simple basée sur des intersections

j'ai une liste multiple:

 list=[[1,2,3],[3,5,6],[8,9,10],[11,12,13]]

Est-il intelligent et rapide façon d'obtenir toutes les sous-listes avec au moins une intersection. Dans mon exemple je veux que le code retourne

 result=[[1,2,3,5,6],[8,9,10],[11,12,13]]
3
demandé sur Community 2012-02-20 02:15:02

3 réponses

cela fonctionne, mais n'est peut-être pas très élégant:

def merge_lists(l):
        s=map(set, l)
        i, n=0, len(s)
        while i < n-1:
                for j in xrange(i+1, n):
                        if s[i].intersection(s[j]):
                                s[i].update(s[j])
                                del s[j]
                                n-=1
                                break
                else:
                        i+=1
        return [sorted(i) for i in s]
0
répondu hochl 2012-02-20 00:10:56

bonne question! C'est beaucoup plus simple si vous pensez à elle comme un-composants problème dans un graphe. Le code suivant utilise l'excellente fonction networkx et la fonction pairs de cette question .

def pairs(lst):
    i = iter(lst)
    first = prev = item = i.next()
    for item in i:
        yield prev, item
        prev = item
    yield item, first

lists = [[1,2,3],[3,5,6],[8,9,10],[11,12,13]]

import networkx
g = networkx.Graph()
for sub_list in lists:
    for edge in pairs(sub_list):
            g.add_edge(*edge)

networkx.connected_components(g)
[[1, 2, 3, 5, 6], [8, 9, 10], [11, 12, 13]]

explication

nous créons un nouveau graphique (vide) g . Pour chaque sous-liste dans lists , examiner ses éléments les noeuds du graphe et Ajouter un bord entre eux. (Puisque nous ne nous soucions que de la connexité, nous n'avons pas besoin d'ajouter tous les bords-seulement adjacents!) Notez que add_edge prend deux objets, les traite comme des noeuds (et les ajoute s'ils ne sont pas déjà là), et ajoute un bord entre eux.

alors, nous trouvons juste les composants connectés du graphe -- un problème résolu! -- et les sortir comme nos ensembles se croisent.

0
répondu Katriel 2017-05-23 12:03:33

Vous pouvez le faire avec un seul passage à travers les données:

list_of_lists = [[1, 2, 3], [3, 5, 6], [8, 9, 10], [11, 12, 13]]
sets = {}
for lst in list_of_lists:
    s = set(lst)
    t = set()
    for x in s:
        if x in sets:
            t.update(sets[x])
        else:
            sets[x] = s
    for y in t:
        sets[y] = s
    s.update(t)
ids = set()
for s in sets.itervalues():
    if id(s) not in ids:
        ids.add(id(s))
        print s

cela crée un dictionnaire sets cartographiant chaque élément à l'ensemble auquel il appartient. Si un élément a déjà été vu, son ensemble est subsumé dans le fichier courant et toutes les entrées dictinaires correspondant au premier ensemble sont mises à jour.

Enfin, nous devons trouver tous les ensembles uniques dans les valeurs du dictionnaire sets . Notez que tandis que je mis en œuvre ceci comme un dictionnaire de sets, le code fonctionne aussi avec des listes au lieu de sets.

0
répondu Sven Marnach 2012-02-22 00:09:44