Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort tuple list with another list

I have a tuple list to_order such as:

to_order = [(0, 1), (1, 3), (2, 2), (3,2)]

And a list which gives the order to apply to the second element of each tuple of to_order:

order = [2, 1, 3]

So I am looking for a way to get this output:

ordered_list = [(2, 2), (3,2), (0, 1), (1, 3)]

Any ideas?

like image 954
RadaKk Avatar asked Nov 30 '17 08:11

RadaKk


People also ask

How do you sort a list with a tuple?

In python, to sort list of tuples by the first element in descending order, we have to use the sort() method with the parameter ” (reverse=True) “ which will sort the elements in descending order.

How do you sort a list of tuples by second element in Python?

Use the key argument of the sorted() function to sort a list of tuples by the second element, e.g. sorted_list = sorted(list_of_tuples, key=lambda t: t[1]) . The function will return a new list, sorted by the second tuple element.

How do you sort a list of tuples based on two values?

Method #1: Using the Bubble Sort Using the technique of Bubble Sort to we can perform the sorting. Note that each tuple is an element in the given list. Access the second element of each tuple using the nested loops.


1 Answers

You can provide a key that will check the index (of the second element) in order and sort based on it:

to_order = [(0, 1), (1, 3), (2, 2), (3,2)]
order = [2, 1, 3]
print(sorted(to_order, key=lambda item: order.index(item[1]))) # [(2, 2), (3, 2), (0, 1), (1, 3)]

EDIT

Since, a discussion on time complexities was start... here ya go, the following algorithm runs in O(n+m), using Eric's input example:

N = 5
to_order = [(randrange(N), randrange(N)) for _ in range(10*N)]
order = list(set(pair[1] for pair in to_order))
shuffle(order)


def eric_sort(to_order, order):
    bins = {}

    for pair in to_order:
        bins.setdefault(pair[1], []).append(pair)

    return [pair for i in order for pair in bins[i]]


def alfasin_new_sort(to_order, order):
    arr = [[] for i in range(len(order))]
    d = {k:v for v, k in enumerate(order)}
    for item in to_order:
        arr[d[item[1]]].append(item) 
    return [item for sublist in arr for item in sublist]


from timeit import timeit
print("eric_sort", timeit("eric_sort(to_order, order)", setup=setup, number=1000))
print("alfasin_new_sort", timeit("alfasin_new_sort(to_order, order)", setup=setup, number=1000))

OUTPUT:

eric_sort 59.282021682999584
alfasin_new_sort 44.28244407700004
like image 191
Nir Alfasi Avatar answered Oct 13 '22 18:10

Nir Alfasi