Hoi,
Ik heb een lijst van strings en een lijst van tuples die een relatie moet voorstellen. Nu wil ik groepen maken van alle items die steeds wat met elkaar te maken hebben. Ik heb wel een algoritme bedacht die werkt, maar hij schaalt erg slecht en is erg traag. Weet iemand een betere, efficientere en vooral snellere manier?
Ik heb het volgende bedacht (en misschien maakt dit voorbeeld het ook duidelijker):
# Ik maak voor de duidelijkheid 3 lijsten als input
items1 = ['a{0}'.format(i) for i in range(10)]
items2 = ['b{0}'.format(i) for i in range(3)]
items3 = ['c{0}'.format(i) for i in range(3)]
relaties = [ # de lijst van relaties
('a0','b0'),
('a0','c0'),
('b0','c0'),
('a1','b1'),
('b1','c1'),
('a1','c1'),
('b2','c2'),
('a2','c2'),
]
# beginnen met elk item in zijn eigen groep, dit is dus een lijst van lists
groups = [[i,] for i in items1 + items2 + items3]
# een paar hulp functies
def findindex(group, item):
"""
een functie om per item de index te vinden van de group waar hij inzit
"""
for g in group:
if item in g:
return group.index(g)
return None # return none als niet gevonden is
def optellen(group, index1, index2):
# voegt groepen samen indien ze gevonden zijn en de items niet al in dezelfde groep zit
if not index1 == index2 and index1!=None and index2!=None:
group[index1]+=group[index2]
del group[index2]
return group
# nu uitvoeren
for i1, i2 in relaties:
groups = optellen(groups, findindex(groups, l1), findindex(groups,l2))
Dit werkt (sorry voor de rare volgorde, het is geen script, maar ik heb het uit een ipython-notebook gekopieerd zoals ik aan het klooien was)
de uitkomst is:
groups
[['a0', 'b0', 'c0'],
['a1', 'b1', 'c1'],
['a2', 'b2', 'c2'],
['a3'],
['a4'],
['a5'],
['a6'],
['a7'],
['a8'],
['a9']]
je ziet dus dat niet alle items in een groep een relatie hoeven te hebben, maar dat de relatie ook indirect mag zijn.