Recursion to the rescue! And don't forget reduce!
input_list = [ [1], [1], [1, 2, 3], [4, 1], [5], [5], [6], [7, 8, 9],
[7, 6], [8, 5] ]
def combine(input_list):
input_list = map(set, input_list) # working with sets has some advantages
reduced_list = reduce(combine_reduce, input_list, [])
if len(reduced_list) == len(input_list):
# return the whole thing in the original format (sorted lists)
return map(sorted, map(list, reduced_list))
else:
# recursion happens here
return combine(reduced_list)
def combine_reduce(reduced_list, numbers):
'''
find the set to add the numbers to or append as a new set.
'''
for sub_set in reduced_list:
if sub_set.intersection(numbers):
sub_set.update(numbers)
return reduced_list
reduced_list.append(numbers)
return reduced_list
print combine(input_list)
Prints out:
$ python combine.py
[[1, 2, 3, 4], [5, 6, 7, 8, 9]]
We have two things going on here. The first is reduce: I'm using it to cook the list down, by fitting each element into the resulting list somewhere or appending it, if that didn't work. This does not do the whole job, though, so we repeat this process (recursion!) until reducing does not provide a shorter list.
Also, use of set allows for the handy intersection method. You will notice the line with map(set, input_list) is redundant in recursion. Extracting a wrapper function combine from the inner function combine_inner and placing the formatting / unformatting (from list to set and back) in the outer function is left as an exercise.