Disons que j'ai par exemple la liste imbriquée suivante:
L = [['John','Sayyed'], ['John' , 'Simon'] ,['bush','trump'],
['Sam','Suri','NewYork'],['Suri','Orlando','Canada']]
Comment puis-je regrouper ces sous-listes, en obtenant l'union de sous-listes qui ont un élément commun avec au moins une autre sous-liste au sein du groupe? Donc, pour l'exemple précédent, le résultat devrait être:
[['John','Sayyed','Simon'] ,['bush','trump'],
['Sam','Suri','NewYork','Orlando','Canada']]
Ainsi, les deux premières sous-listes sont jointes alors qu'elles partagent 'John'
. Quelqu'un pourrait-il s'il vous plaît partager ses précieuses pensées?
Vous pouvez utiliser networkx
pour cela. Générez un graphique et ajoutez votre liste sous forme d'arêtes à l'aide de add_edges_from
. Ensuite, utilisez connected_components
, qui vous donnera avec précision une liste d’ensembles des composants connectés dans le graphique:
import networkx as nx
L = [['John','Sayyed'], ['John' , 'Simon'] ,['bush','trump']
G=nx.Graph()
G.add_edges_from(L)
list(nx.connected_components(G))
[{'John', 'Sayyed', 'Simon'}, {'bush', 'trump'}]
Mettre à jour
Dans le cas de sous-listes comportant plus de 2
éléments, vous pouvez obtenir toute la longueur 2
combinations
de chaque sous-liste et les utiliser comme extrémités du réseau:
from itertools import combinations, chain
L = [['John','Sayyed'], [ 'John' , 'Simon'] ,['bush','trump'],
['Sam','Suri','NewYork'],['Suri','Orlando','Canada']]
L2_nested = [list(combinations(l,2)) for l in L]
L2 = list(chain.from_iterable(L2_nested))
#[('John', 'Sayyed'), ('John', 'Simon'), ('bush', 'trump'), ('Sam', 'Suri')...
G=nx.Graph()
G.add_edges_from(L2)
list(nx.connected_components(G))
[{'John', 'Sayyed', 'Simon'},
{'bush', 'trump'},
{'Canada', 'NewYork', 'Orlando', 'Sam', 'Suri'}]
Détails
Explication plus détaillée sur composants connectés :
En théorie des graphes, un composant connecté (ou juste un composant) d'un graphe non dirigé est un sous-graphe dans lequel deux sommets quelconques sont connectés l'un à l'autre par des chemins et qui n'est connecté à aucun sommet supplémentaire dans le supergraph.
En gros, ce code crée un graphique, avec des arêtes de la liste, chaque bord étant composé de deux valeurs u,v
où u
et v
seront des nœuds connectés par ce bord.
Et par conséquent, l'union des sous-listes avec au moins une sous-liste avec un élément commun peut être traduite en un problème de théorie des graphes comme tous les nœuds qui sont accessibles les uns aux autres par les chemins existants. Un exemple de ceci peut être vu dans le graphique suivant , qui a trois composantes connectées:
Si ordre est important et que la liste est longue, vous pouvez utiliser cette méthode en deux temps:
l = [['john', 'sayyid'], ['john', 'simon'], ['b', 't']]
def join(l1, l2):
mset = set(l1)
result = l1[:] # deep copy
for each in l2:
if each in mset:
continue
else:
result.append(each)
return result
Pour fusionner dans la liste principale, vous pouvez simplement appeler la liste par son rang et afficher la liste d'origine:
l1 = l.pop(0)
l2 = l.pop(0)
l.insert(0, join(l1, l2))
>>> l:
[['john', 'sayyid', 'simon'], ['b', 't']]
Une approche simple
L = [['John','Sayyed'], [ 'John' , 'Simon'] ,['bush','trump']]
L[0].extend([x for x in L[1] if x not in L[0]])
L.pop(1)
print(L)
Voir
Pour fusionner 2 listes:
merge = lambda l1, l2: l1 + [ x for x in l2 if x not in l1 ]
Pour être plus efficace, créez une set
sur l1
;