On Monday, January 9, 2017 at 10:19:31 AM UTC+5:30, Steven D'Aprano wrote: > On Monday 09 January 2017 15:09, Chris Angelico wrote: > > > On Mon, Jan 9, 2017 at 2:53 PM, Steven D'Aprano wrote: > >> [(tmp, tmp + 1) for x in data for tmp in [expensive_calculation(x)]] > >> > >> > >> I can't decide whether that's an awesome trick or a horrible hack... > > > > A horrible hack on par with abusing a recursive function's arguments > > for private variables. > > What's wrong with that? That's a perfectly legitimate technique. I prefer to > hide it behind a private function rather than expose it in a public interface: > > # instead of this > def recursive(arg, _internal=None): > """Recursive function. Don't supply the _internal argument.""" > ... > return recursive(arg-1, spam) > > > # I usually prefer this > def recursive(arg): > """Recursive function.""" > return _recursive(arg, spam) > > def _recursive(arg, internal): > ... > > > but that's just polishing the code. > > > > > Much better would be to refactor the append > > part: > > > > def this_and_one(value): > > return value, value + 1 > > I wouldn't call that "much better". Requiring an extra function defeats the > purpose of using a list comp, and it doesn't scale well for multiple list > comps
+1 Id call it (your original) neither an awesome trick nor a horrible hack — just a neat workaround for an obvious lacuna As for Chris' solution there is a simple test to see whether it's worth it: Does the function name make sense? If yes then the subexpression refactored- into-a-function is probably fine. If not the kludgyness shows [Im assuming the real usage is something else and your question is a highly sscce-ed version] -- https://mail.python.org/mailman/listinfo/python-list