使用ipaddress转换CIDR IP地址范围并输出到数据帧

时间:2017-08-09 03:45:07

标签: python python-3.x jupyter-notebook

我在数据框中有一个带有IPv4和IPv6 CIDR IP地址范围的数据帧(如果需要,可以将它们分开)。我希望获取这些范围并创建一个数据框,其中包含该范围内的每个地址,因此我可以将其与另一个数据帧连接以进行一些过滤。

使用ipaddress包,扩展列表的功能是:

Scene

这将生成此IP范围的列表。有谁知道如何放入一系列CIDR范围,所以我不必执行上述n次?如果我将数据框的引用代替上面的IP地址,我会得到一个ValueError,表明它似乎不是IPv4或IPv6网络。

作为Python新手的第二个问题,我需要做些什么才能将这些扩展的范围放入列表或数据框架中?我试过这个:

a = ip.ip_network('103.21.244.0/22')
    for x in a.hosts():
    print(x)

结束了:

a = ip.ip_network('103.21.244.0/22')
ip_list = [] #x for x in a.hosts()
for x in a.hosts():
    ip_list.append(x)
ip_list

我确信有更好的方法,而不是采取输出和重新编写IP地址。

2 个答案:

答案 0 :(得分:0)

a = ip.ip_network('103.21.244.0/22')
ip_list = [] #x for x in a.hosts()
for x in a.hosts():
    ip_list.append(x.compressed) # 
ip_list

答案 1 :(得分:0)

关于第一个问题,如果模块不支持它,恐怕您将无法做到,而且我认为它不会given the docs。除了传统的for循环外,Python还提供了两种将方法应用于列表的方法:

采用map()的方式,对列表的所有项目执行操作,并返回generator的结果:

def get_single_ip_from_cidr(cidr):
    # ...
cidr_list = ["10.0.0.0/8","192.168.0.0/16"]
results_generator = map(get_single_ip_from_cidr, cidr_list)
print(list(results_generator)) # Casting results_generator to list as you cant print generators directly

使用List comprehensions的Python方法:

def get_single_ip_from_cidr(cidr):
    # ...
results = [get_single_ip_from_cidr(cidr_addr) for cidr_addr in cidr_list] 

关于第二个问题,您得到的列表是IPv4Address对象的列表,您只是看到它的字符串表示形式。通过使用help(ipaddress.IPv4Address),您可以看到有两个分别名为compressedexploded的属性都可以产生您想要的值(我假设两者之间的区别仅在IPv6中相关,您可以使用::作为一组零的简写):

a = ip.ip_network('103.21.244.0/22')
ip_list = [addr.compressed for addr in a.hosts()]

Jeff的回答完全相同,但是更加冗长。

因此,您可以重构整个代码,以从网络列表中获取所有主机,如下所示:

import ipaddress as ip

def get_ip_from_cidr(cidr):
    return [addr.compressed for addr in ip.ip_network(cidr)]

cidr_list = ["192.168.0.0/30","10.0.0.0/26"] 
print([get_ip_from_cidr(cidr) for cidr in cidr_list])