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.