Python ipaddress.collapse_addresses 怎样合并连续网段
如果一组网段来自配置文件、访问控制列表或地址池,直接把它们原样输出,往往会留下重复项和可以继续合并的相邻块。Python 标准库的 ipaddress.collapse_addresses() 可以把同一 IP 版本的网络对象交给 CIDR 规则统一折叠,返回更紧凑的网段迭代器。
最小用法是先用ip_network()把输入转换为网络对象,再调用collapse_addresses()。IPv4 和 IPv6 要分批处理;函数只会合并满足前缀对齐条件的网络,不会因为两个网段“看起来相邻”就强行扩大范围。
官方文档:https://docs.python.org/3/library/ipaddress.html#ipaddress.collapse_addresses
先分清它合并的是什么
collapse_addresses() 处理的是 IPv4Network 或 IPv6Network 对象组成的可迭代对象,不是任意字符串列表。它返回一个迭代器,里面仍然是网络对象。
“连续网段”也有一个容易忽略的限制:两个网络不仅要覆盖连续的地址范围,还要能组成一个合法的更大 CIDR 网络。例如 192.0.2.0/25 和 192.0.2.128/25 正好组成 192.0.2.0/24;如果边界没有按更大前缀对齐,函数就会保留为多个结果。

最小写法:输入转换后直接折叠
下面的例子把字符串解析成网络对象,再把返回迭代器转换为列表。注释只标出输入类型、惰性返回值和最终展示这几个关键点。
from ipaddress import collapse_addresses, ip_network
def collapse_cidrs(values: list[str]) -> list[str]:
# 先把文本统一解析为网络对象,strict=False 会屏蔽误写的主机位
networks = [ip_network(value, strict=False) for value in values]
# 函数返回迭代器;物化后更适合交给接口或配置渲染层
collapsed = collapse_addresses(networks)
# 用 str() 输出规范化后的 CIDR 文本
return [str(network) for network in collapsed]
values = [
"192.0.2.128/25",
"192.0.2.0/25",
"192.0.2.0/25", # 重复输入不会让结果重复扩大
]
print(collapse_cidrs(values))
['192.0.2.0/24']
输入顺序不影响这个示例的折叠结果,重复的 /25 也不会把地址范围扩展到 192.0.3.0/24。如果业务还需要保留原始输入顺序,应在合并前另行保存原始列表。
为什么有些相邻网段仍然不能合并
合并的目标必须是一个合法的更大网络。下面的函数把几个边界样例放在一起,便于观察“可合并”“仅相邻”和“重复覆盖”的区别。
from ipaddress import collapse_addresses, ip_network
def show_case(label: str, values: list[str]) -> None:
# strict=False 只负责把带主机位的输入归一化,不改变合并规则
networks = [ip_network(value, strict=False) for value in values]
result = [str(network) for network in collapse_addresses(networks)]
print(f"{label}: {result}")
show_case("两个对齐的 /25", ["192.0.2.0/25", "192.0.2.128/25"])
show_case("两个未形成更大块的 /26", ["192.0.2.0/26", "192.0.2.128/26"])
show_case("大网覆盖小网", ["198.51.100.0/24", "198.51.100.0/25"])
两个对齐的 /25: ['192.0.2.0/24'] 两个未形成更大块的 /26: ['192.0.2.0/26', '192.0.2.128/26'] 大网覆盖小网: ['198.51.100.0/24']
第二组虽然都在同一个 /24 范围内,但中间还有一段没有覆盖,不能直接变成更大的连续块。判断时不要只比较一个网段的结束地址和另一个网段的起始地址,还要检查它们是否能按同一层级的 CIDR 边界配对。
IPv4 和 IPv6 要分开折叠
官方接口明确要求输入中的网络对象不能混合 IP 版本。实际项目常把两种地址都读进同一个列表,因此最好在调用前按 version 分组,或者在发现混合输入时给出业务层错误。
from collections.abc import Iterable
from ipaddress import IPv4Network, IPv6Network, collapse_addresses, ip_network
def collapse_by_version(values: Iterable[str]) -> dict[int, list[str]]:
# 解析阶段统一得到网络对象,同时保留 Python 的版本属性
networks = [ip_network(value, strict=False) for value in values]
groups: dict[int, list[IPv4Network | IPv6Network]] = {4: [], 6: []}
for network in networks:
# 用 version 分组,避免把 IPv4 和 IPv6 一起传给 collapse_addresses
groups[network.version].append(network)
result: dict[int, list[str]] = {}
for version, group in groups.items():
if group:
# 每组单独折叠,并把迭代器转换成稳定的文本结果
result[version] = [str(network) for network in collapse_addresses(group)]
return result
print(collapse_by_version([
"192.0.2.0/25",
"192.0.2.128/25",
"2001:db8::/65",
"2001:db8:0:0:8000::/65",
]))
{4: ['192.0.2.0/24'], 6: ['2001:db8::/64']}
如果不想分组,也可以在进入函数前直接拒绝同时出现版本 4 和版本 6 的输入。这样错误会更早、更容易定位,避免网络策略层悄悄丢掉其中一类地址。
输出接入配置前要固定边界
collapse_addresses() 返回的是迭代器,所以调用一次后就会被消费。要把结果交给多个下游步骤,先转换成列表;要对文本排序,也应排序网络对象或统一的字符串结果,而不是在多个地方重复遍历原迭代器。
from ipaddress import collapse_addresses, ip_network
def compact_for_config(values: list[str]) -> list[str]:
# 解析并折叠后立刻物化,后续渲染、统计都复用同一份结果
collapsed = list(collapse_addresses(ip_network(value, strict=False) for value in values))
# 网络对象支持按网络地址和前缀进行排序,输出顺序更适合配置 diff
collapsed.sort()
return [network.with_prefixlen for network in collapsed]
print(compact_for_config([
"203.0.113.128/25",
"203.0.113.0/25",
"198.51.100.0/24",
]))
['198.51.100.0/24', '203.0.113.0/24']
排序只是输出层的确定性处理,不会改变折叠规则。若下游把网段作为集合比较,建议把 with_prefixlen 结果作为规范化字符串保存,便于日志、缓存键或配置差异对比。

值班排查时可以按这张清单处理
- 先确认列表元素是网络对象,而不是未解析的字符串或接口对象。
- 读取
network.version,混合 IPv4/IPv6 时按版本分组或提前拒绝。 - 对带主机位的输入决定是否使用
strict=False;这一步属于输入归一化,不是合并本身。 - 把返回迭代器物化一次,记录折叠前后的数量和最终 CIDR 文本。
- 用一对明确对齐的网络做回归样例,再用一个未对齐的相邻样例确认没有过度扩大范围。
常见问题
collapse_addresses() 能直接接受字符串吗?
不要这样用。先通过 ip_network() 把字符串解析为网络对象,再传入折叠函数。
IPv4 和 IPv6 可以放在同一个列表里吗?
不可以混合调用。先按 version 分组,分别折叠,或者在业务层拒绝混合输入。
两个网段地址连续就一定会合并吗?
不一定。它们还必须能组成符合边界对齐要求的更大 CIDR 网络;否则结果会保留多个网段。
为什么我第二次遍历结果为空?
返回值是迭代器,第一次遍历后已经消费。把它转成列表后再交给多个处理步骤。
归纳起来,collapse_addresses() 最适合做“同版本网络对象的 CIDR 归并”:先规范化输入,再分版本折叠,最后物化并固定输出。它负责地址范围的紧凑表达,不负责替你决定路由策略、访问权限或设备配置。
Python logging.basicConfig(force=True) 怎样重置根日志配置
- 上一篇
- Python logging.basicConfig(force=True) 怎样重置根日志配置
- 下一篇
- Linux fanotify 怎样读取 FID 事件定位文件对象
-
- 文章 · python教程 | 1小时前 |
- Python logging.basicConfig(force=True) 怎样重置根日志配置
- 434浏览 收藏
-
- 文章 · python教程 | 1小时前 | 线程池 · 并发编程 · python · Python concurrent.futures buffersize Executor.map 并发排队
- Python concurrent.futures map 的 buffersize 怎样限制排队
- 264浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python itertools.islice 怎样截取迭代器而不提前展开
- 383浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python itertools.batched 怎样处理末尾不足一组的数据
- 141浏览 收藏
-
- 文章 · python教程 | 1小时前 | 标准库 · 调试 · python · Python 装饰器 functools.wraps functools.update_wrapper __wrapped__ inspect.unwrap
- Python functools.update_wrapper 怎样保留装饰器元数据
- 174浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python functools.total_ordering 怎样补齐自定义类的比较方法
- 282浏览 收藏
-
- 文章 · python教程 | 2小时前 | python · Python 继承 链式调用 类型标注 typing.Self
- Python typing.Self 怎样标注链式调用的返回类型
- 118浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python pickletools.dis 怎样查看 pickle 字节码结构
- 148浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python types.MappingProxyType 怎样创建只读映射视图
- 203浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- Python sqlite3 URI 文件名怎样打开只读数据库
- 218浏览 收藏
-
- 文章 · python教程 | 1天前 |
- Python tabnanny 怎样定位缩进中混用制表符的问题
- 153浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 821次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 816次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 905次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 876次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 698次使用
-
- Python xml.dom.minidom.unlink 怎样释放不再使用的 DOM 树引用
- 2026-10-27 501浏览
-
- Python typing 怎样用 TypeIs 缩小类型
- 2026-10-24 501浏览
-
- Python sqlite3 Connection serialize 怎么导出数据库快照:备份窗口、内存占用与恢复校验
- 2026-08-26 501浏览
-
- Python监控网页状态:requests异常处理实战
- 2026-05-29 501浏览
-
- TensorFlow模型部署为API的TF Serving方法
- 2026-05-26 501浏览

