loopbackbee
loopbackbee

Reputation: 23332

Sort a list by a key and get the value out without recomputing

I have a score function, and I want to sort a list according to it.

Ordinarily, this is easy (just get sorted(l, key=score)), but I need the scores later in the code, and score is computationally expensive (so I want to avoid scoring twice).


Here's my current code:

scores= map(score, l)
new_l= [el for i,el in sorted(enumerate(l), key=lambda (i,el): scores[i])]

This works, but is a bit confusing and not particularly readable.

What's the best way to achieve this?

Upvotes: 1

Views: 31

Answers (2)

behzad.nouri
behzad.nouri

Reputation: 78011

functools.lru_cache may be useful in here. As in the docs:

Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments.

simply, add the lru_cache to your function:

@lru_cache(maxsize=32)
def score(i):
    ...

Upvotes: 3

thefourtheye
thefourtheye

Reputation: 239653

Create a dictionary, with keys as your elements from l and the corresponding values will be the scores

>>> scores = {el: score(el) for el in l}

And then use scores.get for the key, like this

>>> sorted(l, key=scores.get)

Note: This technique will work only if the elements of l are hashable.

Upvotes: 2

Related Questions