Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python list comprehension - want to avoid repeated evaluation

I have a list comprehension which approximates to:

[f(x) for x in l if f(x)] 

Where l is a list and f(x) is an expensive function which returns a list.

I want to avoid evaluating f(x) twice for every non-empty occurance of f(x). Is there some way to save its output within the list comprehension?

I could remove the final condition, generate the whole list and then prune it, but that seems wasteful.

Edit:

Two basic approaches have been suggested:

An inner generator comprehension:

[y for y in (f(x) for x in l) if y] 

or memoization.

I think the inner generator comprehension is elegant for the problem as stated. In actual fact I simplified the question to make it clear, I really want:

[g(x, f(x)) for x in l if f(x)] 

For this more complicated situation, I think memoization produces a cleaner end result.

like image 289
Stefan Avatar asked Apr 04 '13 13:04

Stefan


People also ask

Does Python list comprehension maintain order?

Yes, the list comprehension preserves the order of the original iterable (if there is one). If the original iterable is ordered (list, tuple, file, etc.), that's the order you'll get in the result. If your iterable is unordered (set, dict, etc.), there are no guarantees about the order of the items.

Why might you use a list comprehension instead of a loop in Python?

List comprehensions are faster than loops in general. It achieves to be faster by loading the entire list into the memory.

What is the advantage of list comprehension in Python?

One main benefit of using a list comprehension in Python is that it's a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don't have to use a different approach for each scenario.

Is list comprehension faster than generator?

Thus, generator expressions are faster than list comprehension and hence time efficient.


1 Answers

[y for y in (f(x) for x in l) if y] 

Will do.

like image 162
RobertT Avatar answered Oct 02 '22 08:10

RobertT