You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现含字母数字端口字段的字典列表正确排序

MAC-端口映射列表端口字段排序问题

问题场景

开发中需要对存储网络设备MAC地址与端口映射关系的字典列表执行排序操作,初始实现代码如下:

from pprint import pprint
output_list = [{'mac': '0123.4567.89ab', 'port': 'Gi1/0/10'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/1'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/5'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/48'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/1'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/6'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/4'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/13'},
               {'mac': '0123.4567.89ab', 'port': 'Gi8/0/9'},
               {'mac': '0123.4567.89ab', 'port': 'Gi8/0/8'},
               {'mac': '0123.4567.89ab', 'port': 'Te1/1/1'}]

mac_list = sorted(output_list, key=lambda d: "/".join([x for x in d['port'].split("/")]))

pprint(mac_list)

由于port字段是字母与数字混合的字符串格式,默认字符串逐位比较的排序逻辑会导致数字段排序错乱,例如Gi1/0/10会排在Gi1/0/5之前,Python 3.10环境下实际运行输出结果不符合预期:

"C:\Program Files\Python310\python.exe" "C:/Scripts/Python/test1.py"
[{'mac': '0123.4567.89ab', 'port': 'Gi1/0/1'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/10'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/48'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/5'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/6'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/1'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/13'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/4'},
 {'mac': '0123.4567.89ab', 'port': 'Gi8/0/8'},
 {'mac': '0123.4567.89ab', 'port': 'Gi8/0/9'},
 {'mac': '0123.4567.89ab', 'port': 'Te1/1/1'}]

Process finished with exit code 0

预期按端口分段数值逻辑排序,效果如下:

[{'mac': '0123.4567.89ab', 'port': 'Gi1/0/1'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/5'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/6'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/10'},
 {'mac': '0123.4567.89ab', 'port': 'Gi1/0/48'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/1'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/4'},
 {'mac': '0123.4567.89ab', 'port': 'Gi2/0/13'},
 {'mac': '0123.4567.89ab', 'port': 'Gi8/0/8'},
 {'mac': '0123.4567.89ab', 'port': 'Gi8/0/9'},
 {'mac': '0123.4567.89ab', 'port': 'Te1/1/1'}]

故障原因

初始实现直接将拆分后的端口段拼接为字符串作为排序key,使用的是字符串字典序比较规则:逐字符对比ASCII值,数字部分也按单个字符比较。例如字符串"10"的首字符是'1',ASCII值小于字符'5',因此会出现10排在5前面的错乱问题。

实现方案

排序时将端口字符串拆分为「接口类型前缀+多段数字」的结构:字母前缀保留字符串比较逻辑,所有数字段转为整数做数值比较,通过元组逐段对比即可得到符合端口逻辑的排序结果。
可直接运行的实现代码如下:

import re
from pprint import pprint

def get_port_sort_key(port_str: str):
    # 拆分接口类型字母前缀和后续数字部分
    prefix_match = re.match(r'([A-Za-z]+)(.*)', port_str)
    if not prefix_match:
        return (port_str,)
    interface_prefix, num_segment_part = prefix_match.groups()
    # 数字部分按/拆分后转整数,避免字符串排序的数字错乱问题
    num_segments = [int(seg) for seg in num_segment_part.split('/')]
    return (interface_prefix, *num_segments)

output_list = [{'mac': '0123.4567.89ab', 'port': 'Gi1/0/10'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/1'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/5'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/48'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/1'},
               {'mac': '0123.4567.89ab', 'port': 'Gi1/0/6'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/4'},
               {'mac': '0123.4567.89ab', 'port': 'Gi2/0/13'},
               {'mac': '0123.4567.89ab', 'port': 'Gi8/0/9'},
               {'mac': '0123.4567.89ab', 'port': 'Gi8/0/8'},
               {'mac': '0123.4567.89ab', 'port': 'Te1/1/1'}]

mac_list = sorted(output_list, key=lambda item: get_port_sort_key(item['port']))
pprint(mac_list)

运行上述代码即可输出预期的排序结果,该方案兼容常见的Fa(百兆)、Gi(千兆)、Te(万兆)等不同前缀的网络端口格式,数字段长度不固定时也能正常按数值排序。

内容的提问来源于stack exchange,提问作者Ryan Bell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:21:46