List Comprehensions

Chris Angelico rosuav at gmail.com
Mon Dec 22 12:10:25 EST 2014


On Tue, Dec 23, 2014 at 2:18 AM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> Chris Angelico wrote:
>
>> On Mon, Dec 22, 2014 at 8:21 PM, Steven D'Aprano
>> <steve+comp.lang.python at 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



More information about the Python-list mailing list