Python-将IP地址列表转换为地址范围列表

Python-将IP地址列表转换为地址范围列表,python,ip,collapse,Python,Ip,Collapse,有多种方法可以将IP地址列表转换为CIDR列表(NetAddress、ipaddr-py)。有没有办法将IP地址范围列表转换为合并的IP范围 请注意,这是我的一个更一般的问题 以下示例返回以下格式的元组列表:[(开始,结束)] 例1: >>> list_of_ips = ['192.168.0.1', '192.168.0.2', '192.168.0.3'] >>> print merge_ip_list(list_of_ips) [('192.168.0.

有多种方法可以将IP地址列表转换为CIDR列表(NetAddress、ipaddr-py)。有没有办法将IP地址范围列表转换为合并的IP范围

请注意,这是我的一个更一般的问题

以下示例返回以下格式的元组列表:
[(开始,结束)]

例1:

>>> list_of_ips = ['192.168.0.1', '192.168.0.2', '192.168.0.3']
>>> print merge_ip_list(list_of_ips)
[('192.168.0.1','192.168.0.3')]
例2:

>>> list_of_ips2 = ['10.0.0.0', '10.0.0.3', '10.0.0.4']
>>> print merge_ip_list(list_of_ips2)
[('10.0.0.0','10.0.0.0'), ('10.0.0.3','10.0.0.4')]

IMHO一个很好的起点是将虚线字符串转换成int和back。整数表示更便于比较

我想用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

让我给你一些未来的建议。不要要求别人为您编写代码。我之所以帮助你,只是因为我有兴趣将代码尽可能小,并提高我自己的知识。但罗宾汉并不总是在这里。尝试自己开发一些东西,我们将帮助您发现算法和代码中的错误。

为什么不尝试编写一些代码?如果您遇到困难,我们将尝试提供帮助。我不确定如何开始。我的直觉告诉我这需要递归。例如,在将192.168.0.1与192.168.0.2
('192.168.0.1','192.168.0.2')
组合后,需要将结果范围与192.168.0.3
('192.168.0.1'-'192.168.0.3')
组合。这可能是通过递归实现的,但我会先按顺序处理每个项目,然后检查它是否是上一个项目的下一个项目……如果是,你会跟踪,并不断扩展当前范围,直到它不是-然后你开始下一个范围。用以下方法尝试你的程序:list_of_ips=['192.168.0.1','192.168.0.2','192.168.0.3','192.168.0.5']嘿,泰兹,谢谢你的帮助。我真的很感激,因为我根本不知道该怎么开始。我同意这个社区重视帮助其成员,而不是编写完整的代码。事实上,我已经回答了自己的许多问题,在我被推向正确的方向之后。我将分析您的代码并向您报告,希望您能给出一个更好的答案。感谢您修复丢失的
('192.168.0.5','192.168.0.5')
。我会用这个代码来回答我的另一个问题。这很好用。即使元素不是按顺序排列的。例如,在
['192.168.0.1'、'192.168.0.2'、'192.168.0.3'、'192.168.0.5']
['192.168.0.5'、'192.168.0.1'、'192.168.0.2'、'192.168.0.3'.
,或
['192.168.0.3'、'192.168.0.1'、'192.168.0.5'、'192.168.0.2'.
上执行合并\n ip\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r[('192.168.0.1','192.168.0.3'),('192.168.0.5','192.168.0.5')]。谢谢!如果我使用一个大范围,例如10.35.64.0/20,它应该会导致
[('10.35.64.0','10.35.79.255')]
合并ip列表alt()
导致以下错误:
文件,第5行,在merge_ip_list_alt中
值错误:需要超过0个值才能解包
merge_ip_list()
有效。我正在查看并将向您报告。
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 )