This relies on the list of lists being sorted in ascending length (and the outputs needs sorting), but works with all provided input as of time of posting.
def removeFromList(elementsToRemove):
def closure(list):
for element in elementsToRemove:
if list[0] != element:
return
else:
list.pop(0)
return closure
def func(listOfLists):
result = []
for i, thisList in enumerate(listOfLists):
result.append(thisList)
map(removeFromList(thisList), listOfLists[i+1:])
return result
You can remove the closure using more for loops, but it looked too ugly, and too deeply nested.
Edit: based on updates, this is the naive solution to the actual problem:
from itertools import combinations
def isSubsetOrDisjointTo(listA, listB):
return all(item in listB for item in listA) or all(item not in listB for item in listA)
def func(nodesToJoin):
#flatten list, extracting duplicates
allNodes = sorted(set(itertools.chain(*nodesToJoin)))
result = []
seen = set()
for length in xrange(max(map(len, nodesToJoin)), 0, -1):
#start with longest possible, work to shortest
for sublist in combinations(allNodes, length):
if any(item in seen for item in sublist):
#skip possible sublists with options we've already seen in the result
continue
if all(isSubsetOrDisjointTo(sublist, node) for node in nodesToJoin):
result.append(sublist)
seen.update(sublist)
return result
There are probably a number of ways this can be optimised or improved.
1
solved How to breakup a list of list in a given way in Python [closed]