Python如何保留随机嵌套列表结构计算CIDR与IP段IP总数
解决方案
核心问题是现有代码仅支持单层列表遍历,无法适配任意深度、任意元素数量的随机嵌套结构。使用递归遍历即可实现结构1:1保留,无需提前预知列表层级和长度,输出结果可直接传入xlsxwriter匹配行列排布。
优化后完整代码
from netaddr import IPNetwork import re def ip_to_int(ip: str) -> int: """IP字符串转整数,用于范围计数计算""" val = 0 for i, s in enumerate(ip.strip().split('.')): val += int(s) * 256 ** (3 - i) return val def calc_single_ip_count(ip_entry: str, stats: dict) -> int: """单条IP条目(CIDR/横杠范围)转对应地址总数,同时更新统计计数""" ip_entry = str(ip_entry).strip() # 处理横杠分隔的IP范围 if '-' in ip_entry: start_ip, end_ip = ip_entry.split('-', 1) total = ip_to_int(end_ip) - ip_to_int(start_ip) + 1 stats['range_count'] += 1 print("IP range match found") print(f"IP Range: {ip_entry}, number of hosts: {total} \n") return total # 处理CIDR格式网段 else: ip = IPNetwork(ip_entry) total = ip.size stats['cidr_count'] += 1 print("IP CIDR match found") print(f"IP CIDR: {ip_entry}, number of hosts: {total} \n") return total def process_ip_list(input_item, stats: dict): """递归处理任意嵌套结构的IP列表,输出与输入结构完全一致的计数结果""" # 当前元素是列表则递归处理每个子元素,保留原列表层级 if isinstance(input_item, list): return [process_ip_list(sub_item, stats) for sub_item in input_item] # 当前元素是IP条目则直接计算数值 else: return calc_single_ip_count(input_item, stats) # 测试数据 ip_list = ["10.0.14.80/29", "10.56.0.0/29", "10.56.9.0/24", "10.56.68.0/23", "10.56.86.0/23", "10.56.221.0/24", "10.142.0.0/16"] ip_list2 = ["10.0.14.80/29", "10.56.0.0/29", "10.56.9.0/24", "10.56.68.0/23", "10.56.86.0/23", "10.56.221.0/24", "10.142.0.0/16", "10.56.39.0-10.56.40.253"] nested_list1 = [['10.0.14.80/29', '10.56.0.0/29', '10.0.10.16/29'], ['10.0.10.16/29', '10.2.8.0/24'], ['62.118.176.1-68.118.191.254', '209.250.15.1-214.250.15.254'], ['10.0.14.88/29', '10.141.128.0/18']] nested_list2 = [['10.0.14.80/29', '10.56.0.0/29'], ['10.0.10.16/29', '10.2.8.0/24'], ['63.118.176.1-63.118.191.252', '214.220.15.1-218.210.15.254'], ['10.0.14.88/29', '10.141.128.0/18']] if __name__ == "__main__": # 初始化统计计数 stats = {"cidr_count": 0, "range_count": 0} # 传入任意结构的IP列表即可,替换成每日生成的随机嵌套列表即可正常计算 calculated_result = process_ip_list(nested_list1, stats) # 打印统计结果 print(f"Found IP CIDR matches: {stats['cidr_count']} times, and IP Ranges {stats['range_count']} times") print("计算完成,输出结果结构与输入完全一致:") print(calculated_result) print("End of Program")
关键改动说明
- 用递归遍历替代固定层级的for循环:无论输入列表嵌套多少层、每个子列表元素个数是多少,输出结果的层级、元素位置都和输入完全对应,直接可以对接xlsxwriter按行按列写入,不需要提前适配每日随机生成的列表结构。
- 优化了IP范围计数逻辑:去掉原代码中生成全量IP列表再统计长度的低效率实现,直接通过IP整数值的差值计算地址总数,大网段计算速度提升几个数量级,不会出现内存占用过高、计算卡顿的问题。
- 逻辑解耦:单条IP计算、结构遍历、统计计数三个模块完全拆分,后续如果需要新增其他IP格式支持,只需要修改
calc_single_ip_count函数即可,不需要调整遍历逻辑。
内容的提问来源于stack exchange,提问作者Garrett Strahan
相关产品推荐
相关产品推荐

