I have a list of dictionaries that I'm trying to sort. This is what I have so far:
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)
However, it's not sorting the dictionaries the way I want.
"C:\Program Files\Python310\python.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
How can I get it to sort it so it looks like this:
[{'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'}]
CodePudding user response:
Try this:
mac_list = sorted(output_list, key=lambda d: int(d['interface'].split("/")[1]))
If interface
values could start with something other than 0
, and you want it to be part of the sorted value, then you could use something like:
mac_list = sorted(output_list, key=lambda d: int(d['interface'].split("/")[0]) * 10000 int(d['interface'].split("/")[1]))
CodePudding user response:
I am not sure if the first number of interface can be more than zero but if not this change helps. You want to only check the number after /:
mac_list = sorted(output_list, key=lambda d: int(d["interface"][2:]))
output is:
[{'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'}]
CodePudding user response:
If you always have 0/???
. Try this:
mac_list = sorted(output_list, key= lambda x: int(x['interface'][2:]))
Output:
[{'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'}]
If maybe have ???/???. try this: (How about convert 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:])))
Output:
[{'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'}]
CodePudding user response:
You need to get the number out of the string:
sorted(output_list, key=lambda d: int(d['interface'].split("/")[1]))
This assumes that the first part of the interface won't change.
If it changes, you need to reformat both parts with the leading zero:
sorted(output_list, key=lambda d: "/".join([f"{int(x):02d}" for x in d['interface'].split("/")]))
CodePudding user response:
Use natsort
for natural sorting:
from natsort import natsorted
mac_list = natsorted(output_list, key=lambda d: d['interface'])
Or split and convert to integers:
mac_list = sorted(output_list,
key=lambda d: tuple(map(int, d['interface'].split('/'))))
output:
[{'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'}]
CodePudding user response:
Rather than having a cumbersome looking lambda expression as the key argument, it might be clearer to have a separate function to handle to tuple construction:-
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)