I would like to sort list A based on list B(descending order) such that if two list A,B are
A=["k","a","l","d"]
B=[4,3,7,22]
after sorting, ( sort A based on desc(B) )
A=["d","l","k","a"]
However if B=[0,0,0,0]
I would like A to remain A=["k","a","l","d"]
after sorting too
so wherever values are equal, the original order must be retained.
if B=[0,22,5,0]
and A=["k","a","l","d"]
then, after sorting, A=["a","l","k","d"]
I have tried using A= [x for _,x in sorted(zip(B,A),reverse=True)]
,
- with if
A=["k","a","l","d"]
andB=[0,0,0,0]
, this givesA=["a","d","k","l"]
but I want A to remainA=["k","a","l","d"]
- with if
A=["k","a","l","d"]
andB=[0,22,5,0]
, this givesA=["a","l","d","k"]
but I want A to beA=["a","l","k","d"]
How do I achieve this?
CodePudding user response:
Use the key
parameter of sorted
A = ["k", "a", "l", "d"]
Bs = [[4, 3, 7, 22], [0, 0, 0, 0], [0, 22, 5, 0]]
for B in Bs:
res = [a for _, a in sorted(enumerate(A), key=lambda x: B[x[0]], reverse=True)]
print(B, res)
Output
[4, 3, 7, 22] ['d', 'l', 'k', 'a']
[0, 0, 0, 0] ['k', 'a', 'l', 'd']
[0, 22, 5, 0] ['a', 'l', 'k', 'd']
As an alternative, you could use:
it_B = iter(B)
res = sorted(A, key=lambda _: next(it_B), reverse=True)
Both ideas work because Timsort (the underlying algorithm of sorted
) is stable. Since you are using just one key, when the values are equal, they conserve the appearance order.
CodePudding user response:
You can create a dict that maps A
to B
, and use the mapping as a key function to sort A
:
order = dict(zip(A, B))
output = sorted(A, key=order.get, reverse=True)
Demo: https://replit.com/@blhsing/FailingCloseTruespace#main.py
CodePudding user response:
Easiest method I've found is to use numpy's Argsort.
index = np.argsort(B)
a = a[index]
Order is kept if they are all the same (i.e. [0,0,0,0]
).