如何编写Python脚本去除重复及重叠的IP地址与子网
处理IP列表去重与子网重叠清理的Python脚本
要解决这个问题,我们可以用Python自带的ipaddress模块来处理IP和子网的包含关系,步骤简单直接:
操作步骤
- 先去重:把原始列表转成集合,自动剔除重复的IP/子网。
- 转换为IP对象:将每个条目转换成
ipaddress模块对应的对象(单个IP会被自动转为/32子网),方便后续判断包含关系。 - 过滤重叠条目:遍历每个条目,检查它是否被其他任意一个条目包含。如果没有被包含就保留,被包含则丢弃(比如
192.168.1.1属于192.168.0.0/16,就直接保留大子网)。 - 还原为字符串:把保留的IP对象转回易读的字符串格式,单个IP去掉
/32后缀。
完整代码
import ipaddress # 原始IP列表 ip_related_list = [ '192.168.1.1', '192.168.1.2', '192.168.1.0/24', '192.168.0.0/16', '10.1.1.1', '10.1.1.1', '10.1.1.1', '10.1.1.2', '10.10.0.0/16', '10.20.0.0/16', '10.10.0.0/16' ] # 1. 去重 unique_ips = list(set(ip_related_list)) # 2. 转换为ipaddress对象,统一处理子网和单个IP ip_objects = [] for ip_str in unique_ips: try: # 优先解析为子网,strict=False允许单个IP转为/32子网 ip_obj = ipaddress.ip_network(ip_str, strict=False) ip_objects.append(ip_obj) except ValueError: # 兜底处理纯IP地址 ip_obj = ipaddress.ip_address(ip_str) ip_objects.append(ipaddress.ip_network(f"{ip_obj}/32", strict=False)) # 3. 过滤被其他子网包含的冗余条目 filtered = [] for current in ip_objects: is_redundant = False for other in ip_objects: if current != other and other.supernet_of(current): is_redundant = True break if not is_redundant: filtered.append(current) # 4. 转换回字符串格式,单个IP去掉/32后缀 result = [] for ip in filtered: if ip.prefixlen == 32: result.append(str(ip.network_address)) else: result.append(str(ip)) # 输出结果 for item in result: print(f"{item},")
运行结果
运行代码后会输出预期内容:
192.168.0.0/16, 10.10.0.0/16, 10.20.0.0/16, 10.1.1.1, 10.1.1.2,
关键细节
ipaddress.ip_network(..., strict=False):这个参数允许把单个IP解析成/32子网,让我们可以用统一的逻辑判断包含关系。other.supernet_of(current):直接判断other子网是否包含current(不管current是单个IP还是小子网),一键识别冗余条目。
内容的提问来源于stack exchange,提问作者marty
相关产品推荐
相关产品推荐

