'How do you sort a nested list by specific strings that I pass into the sorted lambda?
I've got a nested list which looks like:
mylist = [[123, "PASS"], [123, "FAIL"], [123, "N/A"]]
I have a sorted lambda to sort this alphabetically which looks like:
mylist = sorted(mylist, key=lambda x: (x[1]))
This works how I expected, but not what I want it to work like. This would return a list that when printed will have it like FAIL -> N/A -> PASS
Instead, I want PASS -> FAIL -> N/A, so not alphabetically, almost a custom sort. I have hundreds of pass elements, hundreds of fail elements and hundreds of N/A elements.
What is the best way to create a 'custom' sort based off strings that I expect to go in order.
Solution 1:[1]
You can do it with a dictionary:
sort_order = {'PASS': 0, 'FAIL': 1, 'N/A':2}
mylist = [[123, "PASS"], [123, "FAIL"], [123, "N/A"]]
mylist.sort(key=lambda val: sort_order[val[1]])
mylist
Output:
[[123, 'PASS'], [123, 'FAIL'], [123, 'N/A']]
Edit:
Note that using mylist.sort(...) is (slightly) faster than reassigning mylist to sorted(...) as has been proposed by others.
Solution 2:[2]
You can specify the order:
order = ["PASS", "FAIL", "N/A"] # desired order of items
sorted(mylist, key = lambda x: order.index(x[1])) # order based upon where
# x[1] is in order
Solution 3:[3]
use a lookup table - see below
lookup = {'PASS':0,'FAIL': 1,'N/A':2}
mylist = [[123, "PASS"], [123, "FAIL"], [123, "N/A"]]
mylist = sorted(mylist, key=lambda x: lookup[x[1]])
print(mylist)
output
[[123, 'PASS'], [123, 'FAIL'], [123, 'N/A']]
Solution 4:[4]
You can do this a bit "manually" by creating a new list using:
newlist=[item for item in mylist if item[1]=='PASS']+[item for item in mylist if item[1]=='FAIL']+[item for item in mylist if item[1]=='N/A']
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | DarrylG |
| Solution 3 | balderman |
| Solution 4 |
