list comprehension question

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Wed May 6 00:10:32 EDT 2009


On Tue, 05 May 2009 20:36:37 -0700, alex23 wrote:

> On May 6, 4:01 am, "J. Cliff Dyer" <j... at sdf.lonestar.org> wrote:
>> The way you have to bounce your eyes back and forth in the
>> comprehension makes it hard to read the logic.  With the loop, on the
>> other hand it is blatantly obvious which way the nesting occurs.
> 
>> > >>>> [ item for j in a if len(j)==2 for item in j if item % 2 ]
>> > > ...opposed to...
>> > >>>> for j in a:
>> > > ...     if len(j)==2:
>> > > ...         for item in j:
>> > > ...             if item % 2:
>> > > ...                 b.append(item) ...
> 
>> Much nicer.  Thank you.
> 
> Apart from the presence of 'item' at the beginning of the list
> comprehension as opposed to 'b.append(item)' at the end of the for-
> loop, how exactly does the listcomp force you to "bounce [..] back and
> forth" to follow the logic? The only other difference between the two is
> in the layout - the indentation & colons - otherwise they're
> structurally identical.


It's precisely the indentation and colons (plus newlines) that makes 
nested for-loops easier to read than list-comps with multiple fors.

for a in alist:
    for b in blist:
        for c in clist:
            if c:
                parrot(a, b, c)


is much easier to read than the equivalent one-liner:

[parrot(a, b, c) for a in alist for b in blist for c in clist if c]

You can get back *nearly* all the readability by splitting the list comp 
into multiple lines:

[parrot(a, b, c) 
    for a in alist 
      for b in blist
        for c in clist if c
]



-- 
Steven



More information about the Python-list mailing list