Home > database >  Sort by order of another list, where that list is nested with 2 sort keys, using Python
Sort by order of another list, where that list is nested with 2 sort keys, using Python

Time:01-03

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
  • Related