Temporary variables in list comprehensions
Tim Chase
python.list at tim.thechases.com
Mon Jan 9 07:15:31 EST 2017
On 2017-01-09 02:46, Paul Rubin wrote:
> > gen = (expensive_calculation(x) for x in data)
> > result = [(tmp, tmp + 1) for tmp in gen]
>
> result = [(tmp, tmp+1) for tmp in map(expensive_calculation, data)]
As charmingly expressive as map() is, the wildly different behavior in
py3 (it's a generator that evaluates lazily) vs py2 (it consumes the
entire iterable in one go) leads me to avoid it in general,
especially when Python gives me list-comprehensions and generators
that can do what I intend explicitly. E.g., passing in
itertools.count() as an iterable to map() will kill py2 but is
perfectly fine in py3 (a horrible example):
import itertools as i
for x in i.takewhile(
lambda n: n < 100,
map(lambda g: g**2, i.count())
):
print(x)
But yes, both ChrisA's pass-it-to-a-function and Serhiy's nested
generate-the-tmp-values-then-operate-on-those are good solutions
depending on how they feel in any particular context. If I need to
use an "if" clause in the outer generator that tests the resulting
temp values, I use Serhiy's solution:
[(tmp, tmp + 1)
for tmp in (
expensive_calculation(x)
for x in data
)
if tmp > 42
]
Otherwise, I like the cleanliness of ChrisA's function:
def fn(x)
tmp = expensive_calculation(x)
return x, x + 1
[fn(x) for x in data]
-tkc
More information about the Python-list
mailing list