Python:字典列表的编辑与值处理——移除Po类接口并提取Vlan编号
优化处理VRF字典列表中接口条目的方法
要实现你描述的需求,最Pythonic且高效的方式是结合字典推导式与列表推导式,一次性完成所有接口的过滤和转换操作。这种方法代码简洁、可读性强,而且因为利用了Python内置的推导式优化,执行效率也很高。
实现代码
# 原VRF字典列表 vrfs = [ {'default_rd': '<not set>', 'interfaces': ['Gi0/0'], 'name': 'Mgmt-vrf', 'protocols': 'ipv4,ipv6'}, {'default_rd': '12345:510', 'interfaces': ['Po31.510', 'Po32.510', 'Vl503', 'Vl510', 'Vl515'], 'name': 'VLAN1', 'protocols': 'ipv4,ipv6'}, {'default_rd': '12345:993', 'interfaces': ['Po31.993', 'Po32.993', 'Vl993'], 'name': 'VLAN2', 'protocols': 'ipv4,ipv6'}, {'default_rd': '12345:855', 'interfaces': ['Po31.855', 'Po32.855', 'Vl855'], 'name': 'VLAN3', 'protocols': 'ipv4,ipv6'}, {'default_rd': '12345:266', 'interfaces': ['Po31.266', 'Po32.266', 'Vl266'], 'name': 'VLAN4', 'protocols': 'ipv4,ipv6'}, {'default_rd': '12345:248', 'interfaces': ['Po31.248', 'Po32.248', 'Vl248'], 'name': 'VLAN5', 'protocols': 'ipv4,ipv6'} ] # 处理后的VRF列表 processed_vrfs = [ {**vrf, 'interfaces': [ intf[2:] if intf.startswith('Vl') else intf for intf in vrf['interfaces'] if not intf.startswith('Po') ]} for vrf in vrfs ] # 验证结果(可选) import pprint pprint.pprint(processed_vrfs)
代码解释
- 外层列表推导式:遍历原
vrfs中的每个VRF字典,生成处理后的新字典。 - 字典扩展语法
{**vrf, ...}:复制原字典的所有键值对,然后覆盖interfaces字段为处理后的结果,这样不会修改原字典的其他内容。 - 内层列表推导式:
- 先通过
if not intf.startswith('Po')过滤掉所有以Po开头的接口; - 对剩下的接口,判断如果是以
Vl开头,就截取从第3个字符开始的子串(也就是去掉Vl前缀),否则直接保留原接口名(比如Gi0/0)。
- 先通过
为什么这是最优方法?
- 简洁性:用一行嵌套推导式完成所有逻辑,代码紧凑且易读;
- 高效性:Python的推导式是底层优化过的,比手动写
for循环+append的执行速度更快; - 安全性:生成新的字典列表,不会修改原数据,避免了意外的副作用;
- 可扩展性:如果后续需要添加新的接口处理规则,只需要在列表推导式中补充判断逻辑即可。
如果确实需要直接修改原列表(不推荐,除非必要),可以用循环遍历每个字典并更新interfaces字段:
for vrf in vrfs: vrf['interfaces'] = [ intf[2:] if intf.startswith('Vl') else intf for intf in vrf['interfaces'] if not intf.startswith('Po') ]
内容的提问来源于stack exchange,提问作者Ryan Bell
相关产品推荐
相关产品推荐

