IMHO a good point to start is to make converters from dotted string into int and back. Integer representation is more convenient to compare.
I thought about using reduce but it seems too difficult for me. So I've just implemented it using traditional loop and without recursion.
def int2dot( intip ):
return '.'.join([ str( (intip>>x*8) & 0xFF ) for x in [3,2,1,0]])
def dot2int( dotip ):
return reduce( lambda r,x: int(x)+(r<<8), dotip.split('.'), 0 )
def merge_ip_list(ip_list):
if not ip_list:
return []
orig = map(dot2int,ip_list)
orig.sort()
start = orig[0]
prev = start-1
res = []
for x in orig:
if x != prev+1:
res.append((int2dot(start),int2dot(prev)))
start = x
prev = x
res.append((int2dot(start),int2dot(prev)))
return res
EDIT: bug fixed.
Also I've made an alternative solution:
def merge_ip_list_alt(ip_list):
if not ip_list:
return []
orig = sorted(map(dot2int,ip_list))
end, start = zip(*[x for x in zip(orig,orig[1:]) if x[0]+1!=x[1]]) or ((),())
start = [int2dot(orig[0])] + map(int2dot,start)
end = map(int2dot,end) + [int2dot(orig[-1])]
return zip( start, end )
Let me give you some advice for the future. Do not ask people to write code for you. I helped you just because I was interested to make the code as small as I can and improve my own knowledges. But Robin Hood is not always here. Try to develop something yourself and we will help you to find your mistakes in algorithms and code.