list_1 = [2, 7, 4, 5, 6, 1, 3, 8, 9]
list_2 = [(1, 5), (2, 0), (3, 6), (4, 4), (5, 3), (6, 2), (7, 1), (8, 7), (9, 8)]
I want to reorder list list_2
such that the first element of each tuple follows the order specified by list_1
, so:
list_2_ordered = [(2, 0), (7, 1), (4, 4), (5, 3), (6, 2), (1, 5), (3, 6), (8, 7), (9, 8)]
I try to use the map
function to map filter
over the list_1
as iterables (the general idea map(filter(lambda x,j : x[0]==j, list_2),list_1)
. But of course it doesn't work (I think due to type error). How can I do this with the least number of code lines?
CodePudding user response:
Craft a dictionary to map your sorting order (the key being your number and the value the order in list_1) and use sorted
with a custom key
that will map the first item to the dictionary (and thus the expected order):
order = {k:v for v,k in enumerate(list_1)}
list_2_ordered = sorted(list_2, key=lambda x: order.get(x[0], float('inf')))
Output:
[(2, 0), (7, 1), (4, 4), (5, 3), (6, 2), (1, 5), (3, 6), (8, 7), (9, 8)]
NB. I used order.get
with float('inf')
as second parameter to handle the case where the first item is not present in order
. In this case, the tuple will be sorted at the end. If you use -1
as default value, this will sort the unknown keys at the beginning
CodePudding user response:
Here's one way to get your desired outcome in two steps:
(i) Create dictionary dic1
to lookup the position of each item in list1
(ii) Sort list_2
by the first elements using their positions in list_1
with dictionary dic1
dic1 = {k:v for k,v in zip(list_1, range(len(list_1)))}
list_2.sort(key = lambda x: dic1[x[0]])
print(list_2)
Output:
[(2, 0), (7, 1), (4, 4), (5, 3), (6, 2), (1, 5), (3, 6), (8, 7), (9, 8)]
CodePudding user response:
If you want to do it in the fewest lines of code:
>>> list_2.sort(key=lambda t: list_1.index(t[0]))
>>> list_2
[(2, 0), (7, 1), (4, 4), (5, 3), (6, 2), (1, 5), (3, 6), (8, 7), (9, 8)]
Other solutions here that involve creating a dict are more efficient for large lists (that index
call is O(n) so it takes the sort from O(n log n) to O(n^2)), but for a small list like this, the difference is likely to be negligible.
CodePudding user response:
The key
you need is even simpler than represented by the other answers.
list1.index(a)
tells you the position of a
within list1
, if applicable. You want to sort the x
s found in your list2
according to (i.e., key
ed by) the position of x[0]
within list1
, i.e., according to list1.index(x[0])
(and all of our x[0]
values are indeed in list1
, so there is no potential exception); x
is a lambda
parameter (i.e., a name that we used in the previous sentence in order to explain the rule), so we have our key=lambda x: list1.index(x[0])
; we want to .sort
our list2
with that key
, so we write it directly:
list_2.sort(key=lambda x: list1.index(x[0]))
No need to build anything else.
CodePudding user response:
You can pass a "key" function to the lists sort function in python. This determines the order of the sorted list!
list_2.sort(key=lambda x: list_1.index(x[0]))
print(list_2)