On Tue, Dec 23, 2014 at 2:18 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > Chris Angelico wrote: > >> On Mon, Dec 22, 2014 at 8:21 PM, Steven D'Aprano >> <steve+comp.lang.pyt...@pearwood.info> wrote: >>> If the called function has side-effects, a list comp is not a good >>> solution. >> >> Hmm. I'm not so sure about that. Side effects are fine in a list comp, >> as long as you're making use of the return values. For instance, if >> you have a function that inserts a record to a database and returns >> the new ID, you could reasonably use a list comp to save a bunch of >> records and get a list of IDs for subsequent use. > > I hear what you are saying, but a list comprehension is a functional idiom. > To mix functional and procedural idioms in the one expression is rather > icky. Better to use one or the other but not both simultaneously. > > I'll accept that this is a weak recommendation though.
In my opinion, trying to separate functional and procedural idioms is like trying to separate 'for' loops and recursion; they're two tools that can be used separately or together, in whatever way makes the most sense. Given that side-effecting functions are a mess in functional programming anyway, of course they cause problems for functional idioms; but if it's okay to have side effects at all, it ought to be okay to have side effects of a list comp. A list comp should take an (or several) input iterable(s) and produce an output list. My personal expectation is that it should step through the entire iterable, and every element of it should be "eyeballed": if there's an 'if'' clause, they might not all produce output elements, but they all at least had a chance to. The input iterable and its contents shouldn't be changed in the process, other than being consumed (if it's a one-shot iterator/generator). Side effects are fine, just as long as the output list is important to the code. Of course, that's just *my* expectation. As we've seen before, expectations can differ; several of us believe that "while x:" implies that x is able to become false (either through mutation or through rebinding) during the loop, and others see it as equally viable for it to mean "if x: while True:". I suspect our various backgrounds influence our Python styles fairly strongly. And that's a good thing - we aren't all forced into one style. ChrisA -- https://mail.python.org/mailman/listinfo/python-list