Python实现IP列表连续段合并:现有代码末段生成失败排查
问题描述
给定IP列表:
list_of_ips = ['10.0.0.10', '10.0.0.11', '10.0.0.12', '10.0.0.13', '10.0.0.40', '10.0.0.43', '10.0.0.44', '10.0.0.45', '10.0.0.46', '10.0.0.47', '10.0.0.48', '10.0.0.49', '10.0.0.50', '10.0.0.51', '10.0.0.52', '10.0.0.53', '10.0.0.54', '10.0.0.55', '10.0.0.56', '10.0.0.57', '10.0.0.58', '10.0.0.59', '10.0.0.60']
需求:将列表中连续的IP段用短横线(-)合并,非连续的IP保留单个形式,示例输出如下:
output = ['10.0.0.10-10.0.0.13', '10.0.0.40', '10.0.0.43-10.0.0.60']
现有代码无法生成最后一段IP范围10.0.0.43-10.0.0.60,排查并修正如下:
原代码问题分析
- 逻辑冗余混乱:
compare_ips返回值设计复杂,后续分支处理重复且错误,比如check==99时的操作完全没必要,反而破坏分组逻辑。 - 遗漏收尾处理:循环仅处理相邻IP对,遍历结束后未处理最后一组连续IP,导致最后一段范围无法生成。
- 变量命名冲突:使用Python内置函数名
range作为变量,可能引发潜在错误。 - 分组不完整:连续IP仅将前一个加入
group,最后一个IP从未被正确纳入组内生成范围。
修正后的代码
def is_consecutive(ip1, ip2): # 检查两个IP是否连续(前三位相同,最后一位差1) octets1 = list(map(int, ip1.split('.'))) octets2 = list(map(int, ip2.split('.'))) if octets1[:3] != octets2[:3]: return False return octets2[3] - octets1[3] == 1 def merge_ip_ranges(ip_list): if not ip_list: return [] merged = [] start = end = ip_list[0] for ip in ip_list[1:]: if is_consecutive(end, ip): end = ip else: # 加入当前组到结果 merged.append(start if start == end else f"{start}-{end}") start = end = ip # 处理最后一组未加入的IP merged.append(start if start == end else f"{start}-{end}") return merged # 测试 list_of_ips = ['10.0.0.10', '10.0.0.11', '10.0.0.12', '10.0.0.13', '10.0.0.40', '10.0.0.43', '10.0.0.44', '10.0.0.45', '10.0.0.46', '10.0.0.47', '10.0.0.48', '10.0.0.49', '10.0.0.50', '10.0.0.51', '10.0.0.52', '10.0.0.53', '10.0.0.54', '10.0.0.55', '10.0.0.56', '10.0.0.57', '10.0.0.58', '10.0.0.59', '10.0.0.60'] output = merge_ip_ranges(list_of_ips) print(output) # 输出结果: ['10.0.0.10-10.0.0.13', '10.0.0.40', '10.0.0.43-10.0.0.60']
修正说明
- 替换原
compare_ips为is_consecutive,直接返回布尔值判断IP是否连续,逻辑更清晰。 - 用
start和end跟踪当前连续组的首尾,遍历过程中动态更新边界。 - 遍历结束后强制处理最后一组IP,避免遗漏。
- 避免使用内置函数名作为变量,消除命名冲突风险。
- 增加空列表的边界处理,提升代码健壮性。
内容的提问来源于stack exchange,提问作者miu
相关产品推荐
相关产品推荐

