Reputation: 29445
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.
Upvotes: 1
Views: 71
Reputation: 5613
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
.
Upvotes: 5
Reputation: 33714
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"]
@Moe A’s answer using dict.get(x, 0)
, with a timeit value of 2.42482
@abccd’s answer (mine) using defaultdict
, with a timeit value of 2.88044
@RomanPerekhrest’s answer using two sorted
function, with a timeit value of 2.97899
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.
Upvotes: 2
Reputation: 92854
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']
Upvotes: 1