How to sort one list based on another?
Question:
I have two list, one reference and one input list
Ref = [3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4]
Input = [9, 5, 2, 3, 10, 4, 11, 8]
I want to sort Input list, in the order as that of Ref. If some element is missing in Input list, it can skip and go for the other element.
Hence sorted Input list, based on Ref list will be like this
Sorted_Input = [3, 2, 11, 10, 9, 8, 5, 4]
Answers:
I think this answers your question:
>>> [x for x in Ref if x in Input]
>>> [3, 2, 11, 10, 9, 8, 5, 4]
Hope it helps.
UPDATE:
Making Input
a set
for faster access:
>>> Input_Set = set(Input)
>>> [x for x in Ref if x in Input_Set]
[3, 2, 11, 10, 9, 8, 5, 4]
Another approach in addition to dcg’s answer would be as follows:
Ref = [3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4]
Input = [9, 5, 2, 3, 10, 4, 11, 8]
ref = set(Ref)
inp = set(Input)
sorted_list = sorted(ref.intersection(inp), key = Ref.index)
This outputs to:
[3, 2, 11, 10, 9, 8, 5, 4]
Here you convert the lists into sets, find their intersection, and sort them. The set is sorted based on the ‘Ref’ list’s indexing.
You can use the sorted method:
# keep in a dict the index for each value from Ref
ref = {val: i for i, val in enumerate(Ref)}
# sort by the index value from Ref for each number from Input
sorted(Input, key=ref.get)
output:
[3, 2, 11, 10, 9, 8, 5, 4]
Here’s the naive approach:
sorted(Input, key=Ref.index)
Or in-place:
Input.sort(key=Ref.index)
Either way it’s just one line.
Although I think it’s slow — O(n*m) where n and m are the lengths of Input
and Ref
. @rusu_ro1’s solution uses a similar method but seems to be O(n+m).
I have two list, one reference and one input list
Ref = [3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4]
Input = [9, 5, 2, 3, 10, 4, 11, 8]
I want to sort Input list, in the order as that of Ref. If some element is missing in Input list, it can skip and go for the other element.
Hence sorted Input list, based on Ref list will be like this
Sorted_Input = [3, 2, 11, 10, 9, 8, 5, 4]
I think this answers your question:
>>> [x for x in Ref if x in Input]
>>> [3, 2, 11, 10, 9, 8, 5, 4]
Hope it helps.
UPDATE:
Making Input
a set
for faster access:
>>> Input_Set = set(Input)
>>> [x for x in Ref if x in Input_Set]
[3, 2, 11, 10, 9, 8, 5, 4]
Another approach in addition to dcg’s answer would be as follows:
Ref = [3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 4]
Input = [9, 5, 2, 3, 10, 4, 11, 8]
ref = set(Ref)
inp = set(Input)
sorted_list = sorted(ref.intersection(inp), key = Ref.index)
This outputs to:
[3, 2, 11, 10, 9, 8, 5, 4]
Here you convert the lists into sets, find their intersection, and sort them. The set is sorted based on the ‘Ref’ list’s indexing.
You can use the sorted method:
# keep in a dict the index for each value from Ref
ref = {val: i for i, val in enumerate(Ref)}
# sort by the index value from Ref for each number from Input
sorted(Input, key=ref.get)
output:
[3, 2, 11, 10, 9, 8, 5, 4]
Here’s the naive approach:
sorted(Input, key=Ref.index)
Or in-place:
Input.sort(key=Ref.index)
Either way it’s just one line.
Although I think it’s slow — O(n*m) where n and m are the lengths of Input
and Ref
. @rusu_ro1’s solution uses a similar method but seems to be O(n+m).