On Monday, January 9, 2017 at 5:54:15 PM UTC+5:30, Tim Chase wrote: > 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 > ]
What happens when the expensive is on an inner generator? Something like: [expensive₂(y) for x in data for y in foo(x)] [The ₂ representing the 2 or more occurrences in Steven's eg] -- https://mail.python.org/mailman/listinfo/python-list