简体   繁体   中英

How to sort a list according to a list of lists in python?

I have a list:

a = ["x", "y", "z"]

I have another list of lists:

b = [["y", 99], ["w", 65], ["z", 150]]

So, I would like to sort items in a , according to the values in b in descending order, thus the sorted a should look like:

sorted_a = ["z", "y", "x"]

here "x" is on the last, because it doesn't have a value in b .

I would like to know the fastest way of achieving this, because my real lists are large.

You can convert b to a dictionary and sort using dict.get() as the key with a default value of 0, for example:

a = ["x", "y", "z"]
b = [["y", 99], ["w", 65], ["z", 150]]

lowest = float('-inf')
tmp = dict(b)
sorted_a = sorted(a, key=lambda x: tmp.get(x, lowest), reverse=True)
# sorted_a = ["z", "y", "x"]

Edit:

To avoid wrong results when having negative numbers, I changed the default value for .get() to -inf so the elements that don't exist in b come last in the sorted list. Keep it as tmp.get(x, 0) if you don't have negative values in b .

You can use a defaultdict and add the values from b to the defaultdict , then change the key of sorted to b_dict[x] , which will sort according to the value associated with x in b , if the value doesn't exist in b , the default value was 0 , so it will be sorted to last.

from collections import defaultdict

a = ["x", "y", "z"]
b = [["y", 99], ["w", 65], ["z", 150]]

b_dict = defaultdict(int, b)

sorted_a = sorted(a, key=lambda x: b_dict[x], reverse=True)
print(sorted_a)
#  ["z", "y", "x"]

Speed wise:

  1. @Moe A's answer using dict.get(x, 0) , with a timeit value of 2.42482

  2. @abccd's answer (mine) using defaultdict , with a timeit value of 2.88044

  3. @RomanPerekhrest's answer using two sorted function, with a timeit value of 2.97899

Result:

I would like to know the fastest way of achieving this

Then I would suggest using @Moe A's answer because it is by far the fastest and most simplest out of the three.

With sorted function:

a = ["x", "y", "z"]
b = [["y", 99], ["w", 65], ["z", 150]]
b_sorted = [i[0] for i in sorted(b, key=lambda x: x[1], reverse=True)]
a_sorted = sorted(a, key=lambda x: b_sorted.index(x) if x in b_sorted else len(a))

print(a_sorted)

The output:

['z', 'y', 'x']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM