I find myself often wanting to write Python list comprehensions like this:
nearbyPoints = [(n, delta(n,x)) for n in allPoints if delta(n,x)<=radius]
That hopefully gives some context as to why I would want to do this, but there
are also cases where multiple values need to be computed/compared per
element:
newlist = [(x,f(x),g(f(x))) for x in bigList if f(x)<p and g(f(x))<q]
So I have two questions:
- will all those functions be evaluated multiple times or is the result cached?
Does the language specify or is it implementation-specific? I’m using 2.6 now, but would 3.x be different? - is there a neater way to write it? Sometimes f and g are long expressions and
duplication is error prone and looks messy. I would really like to be able to
write this:
newList = [(x,a=f(x),b=g(a)) for x in bigList if a<p and b<q]
but that doesn’t work. Is there a good reason for not supporting this syntax? Can
it be done via something like this?
Or would I just have to use multiple listcomps or a for-loop?
In regards to #1, yes, they will be evaluated multiple times.
In regards to #2, the way to do it is to calculate and filter in separate comprehensions:
Condensed version:
Longer version expanded to make it easier to follow:
This will call
fandgas few times as possible (values for eachf(x)is not< pwill never callg, andfwill only be called once for each value inbigList).If you prefer, you can also get neater code by using intermediate variables:
aandbuse generator expressions so that they don’t have to actually instantiate lists, and are simply evaluated when necessary.