ИМХО, хороший момент для начала - сделать преобразователи из пунктирной строки в int и обратно. Целочисленное представление удобнее сравнивать.
Я подумал об использовании Reduce, но мне это кажется слишком сложным. Так что я только что реализовал это, используя традиционный цикл и без рекурсии.
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
РЕДАКТИРОВАТЬ : исправлена ошибка.
Также я сделал альтернативное решение:
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 )
Позвольте дать вам совет на будущее. Не просите людей писать код для вас. Я помог вам только потому, что мне было интересно сделать код как можно меньше и улучшить свои знания. Но Робин Гуд не всегда здесь. Попробуйте сами разработать что-нибудь, и мы поможем вам найти ошибки в алгоритмах и коде.