KayP
KayP

Reputation: 29

Sort a list based on the the order of occurence of that value in another list

How to sort values of A based on the order of occurrence in B where values in A may be repetitive and values in B are unique

A=[1, 2, 2, 2, 3, 4, 4, 5] 

B=[8, 5, 6, 2, 10, 3, 1, 9, 4]

The expected list is C which should contain

C = [5, 2, 2, 2, 3, 1, 4, 4]

Upvotes: 0

Views: 309

Answers (3)

Alain T.
Alain T.

Reputation: 42143

You can sort it without actually using a sort. The Counter class (from collection) is a special dictionary that maintains counts for a set of keys. In this case, your B list contains all keys that are possible. So you can use it to initialize a Counter object with zero occurrences of each key (this will preserve the order) and then add the A list to that. Finally, get the repeated elements out of the resulting Counter object.

from collections import Counter

A=[1, 2, 2, 2, 3, 4, 4, 5] 

B=[8, 5, 6, 2, 10, 3, 1, 9, 4]


C = Counter(dict.fromkeys(B,0)) # initialize order
C.update(A)                     # 'sort' A
C = list(C.elements())          # get sorted elements

print(C)
[5, 2, 2, 2, 3, 1, 4, 4]

You could also write it in a single line:

C = list((Counter(dict.fromkeys(B,0))+Counter(A)).elements())

While using sorted(A,key=B.index) is simpler to write, this solution has lower complexity O(K+N) than a sort on an index lookup O(N x K x logN).

Upvotes: 1

U13-Forward
U13-Forward

Reputation: 71580

Solution:

Try using sorted:

C = sorted(A, key=B.index)

And now:

print(C)

Output:

[5, 2, 2, 2, 3, 1, 4, 4]

Documentation reference:

As mentioned in the documentation of sorted:

Return a new sorted list from the items in iterable.

Has two optional arguments which must be specified as keyword arguments.

key specifies a function of one argument that is used to extract a comparison key from each element in iterable (for example, key=str.lower). The default value is None (compare the elements directly).

reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.

Upvotes: 7

Epsi95
Epsi95

Reputation: 9047

you can use the key in sorted function

A=[1, 2, 2, 2, 3, 4, 4, 5] 

B=[8, 5, 6, 2, 10, 3, 1, 9, 4]

C = ((i, B.index(i)) for i in A) # <generator object <genexpr> at 0x000001CE8FFBE0A0>

output = [i[0] for i in sorted(C, key=lambda x: x[1])] #[5, 2, 2, 2, 3, 1, 4, 4]

Upvotes: 2

Related Questions