Python按数字排序字典列表



我有一个字典列表,我正在尝试排序。这是我目前所看到的:

output_list = [{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'}]
mac_list = sorted(output_list, key=lambda d: d['interface'])
pprint(mac_list)

但是,它没有按我想要的方式排序字典。

"C:Program FilesPython310python.exe" "C:/Scripts/Python/test1.py"
[{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'}]
Process finished with exit code 0

我如何让它排序,使它看起来像这样:

[{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'}]

您需要从字符串中获取数字:

sorted(output_list, key=lambda d: int(d['interface'].split("/")[1]))

这假定接口的第一部分不会改变。

如果它改变了,你需要用前导零重新格式化这两个部分:

sorted(output_list, key=lambda d: "/".join([f"{int(x):02d}" for x in d['interface'].split("/")]))

试试这个:

mac_list = sorted(output_list, key=lambda d: int(d['interface'].split("/")[1]))

如果interface值可以以0以外的其他值开始,并且您希望它成为排序值的一部分,那么您可以使用以下内容:

mac_list = sorted(output_list, key=lambda d: int(d['interface'].split("/")[0]) * 10000 + int(d['interface'].split("/")[1]))

我不确定接口的第一个数字是否可以大于零,但如果不是这样的话,这个变化会有所帮助。您只需要检查/:

后面的数字
mac_list = sorted(output_list, key=lambda d: int(d["interface"][2:]))

输出是:

[{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'}, {'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'}, {'interface': '0/16', 'mac': '12:34:56:78:9A:BC'}, {'interface': '0/20', 'mac': '01:23:45:67:89:AB'}, {'interface': '0/31', 'mac': '23:45:67:89:AB:CD'}]

如果你总是有0/???。试试这个:

mac_list  = sorted(output_list, key= lambda x: int(x['interface'][2:]))

输出:

[{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'}]

如果有??/??(如何转换1/3 to 1.3?)

# 1/3 -> 1.3 then get as float and sort
sorted(output_list, key= lambda x: float(x['interface'].replace('/', '.')))
# or as string
sorted(output_list, key= lambda x: (int(x['interface'][:1]),int(x['interface'][2:])))

输出:

[{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'},
{'interface': '1/3', 'mac': '45:67:89:AB:CD:EF'}]

使用natsort自然排序:

from natsort import natsorted
mac_list = natsorted(output_list, key=lambda d: d['interface'])

或拆分并转换为整数:

mac_list = sorted(output_list,
key=lambda d: tuple(map(int, d['interface'].split('/'))))

输出:

[{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'}]

与其使用一个看起来很麻烦的lambda表达式作为参数,不如使用一个单独的函数来处理元组构造:-

output_list = [{'interface': '0/20', 'mac': '01:23:45:67:89:AB'},
{'interface': '0/16', 'mac': '12:34:56:78:9A:BC'},
{'interface': '0/31', 'mac': '23:45:67:89:AB:CD'},
{'interface': '0/5', 'mac': '34:56:78:9A:BC:DE'},
{'interface': '0/3', 'mac': '45:67:89:AB:CD:EF'}]
def mt(s):
return tuple(map(int, s['interface'].split('/')))
mac_list = sorted(output_list, key=mt)
print(mac_list)

最新更新