I have a list of dictionaries that I'm trying to sort. This is what I have so far:
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)
However, it's not sorting the dictionaries the way I want.
"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
How can I get it to sort it so it looks like this:
[{'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'}]
CodePudding user response:
Try:
out = sorted(
output_list,
key=lambda d: (d["port"][:2], *map(int, d["port"][2:].split("/"))),
)
print(out)
Prints:
[
{"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"},
]
Note:
(d["port"][:2], *map(int, d["port"][2:].split("/")))
will create tuple in form ('Gi', 1, 0, 48)
etc. The sorted()
function will then sort according these tuples.
CodePudding user response:
Try this:
mac_list = sorted(output_list, key=lambda d: tuple(int(x) if x.isdigit() else x for x in d['port'].split("/")))
This will convert numeric strings to int
values in the substrings of the port
value produced by split()
and leave non-numeric strings as is, and sorting based on the resulting tuple
values will get you the desired output.
CodePudding user response:
Seems that you're looking for human/natural sorting. This answer covers it well.
Using the natural_keys
function from that answer, the port string could then be passed directly to the defined function as follow:
output_list.sort(key=lambda d: natural_keys(d["port"]))