I know how to sort one list to match the order of another list. I also know how to sort one list on two keys (using a lamdba function like key = lambda i: (i[0], i[1])
). But I need to sort one list to match the order of another list, where that second list has two sort keys. For example:
order_list = [['a', 2], ['c', 3], ['b', 1], ['e', 4]]
listB = [['c', 3, 'red', 'car'], ['e', 4, 'green', 'bus'], ['b', 1, 'blue', 'bike'], ['a', 2, 'yellow', 'plane']]
Desired output:
sorted_listB = [['a', 2, 'yellow', 'plane'], ['c', 3, 'red', 'car'], ['b', 1, 'blue', 'bike'],['e', 4, 'green', 'bus']]
I tried by writing this - even though it's bad form I just wanted to see if it would work and it does not:
def sort_key(x):
""" Find the matching element in reference sorted list
"""
# bad form, referencing non-local var
for a in order_list:
if a[0] == x[0] and a[1] == x[1]:
return a
sorted_listB = sorted(listB, key = sort_key)
Any clever thoughts on how to do this? Preferably without turning the nested list into a single key. I know I can do that...was trying to stretch my skills and do it this way, but I'm stuck.
CodePudding user response:
One approach:
order_list = [['a', 2], ['c', 3], ['b', 1], ['e', 4]]
listB = [['c', 3, 'red', 'car'], ['e', 4, 'green', 'bus'], ['b', 1, 'blue', 'bike'], ['a', 2, 'yellow', 'plane']]
# use a dictionary to map the values to the priorities
keys = {tuple(e): i for i, e in enumerate(order_list)}
# then use the first to elements of each sub-list to check for the priority
sorted_listB = sorted(listB, key=lambda x: keys.get(tuple(x[:2])))
print(sorted_listB)
print(sorted_listB)
Output
[['a', 2, 'yellow', 'plane'], ['c', 3, 'red', 'car'], ['b', 1, 'blue', 'bike'], ['e', 4, 'green', 'bus']]
Or, if you wish, fix your function to return index values using enumerate
as below:
def sort_key(x):
""" Find the matching element in reference sorted list
"""
# bad form, referencing non-local var
for i, a in enumerate(order_list):
if a[0] == x[0] and a[1] == x[1]:
return i