Temporary variables in list comprehensions

Rustom Mody rustompmody at gmail.com
Mon Jan 9 00:51:03 EST 2017


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]



More information about the Python-list mailing list