Split a list into two parts based on a filter?

Roy Smith roy at panix.com
Wed Jun 12 07:39:51 EDT 2013


In article <mailman.3050.1371018754.3114.python-list at python.org>,
 Phil Connell <pconnell at gmail.com> wrote:

> > Well, continuing down this somewhat bizarre path:
> >
> > new_songs, old_songs = [], []
> > itertools.takewhile(
> >     lambda x: True,
> >     (new_songs if s.is_new() else old_songs).append(s) for s in songs)
> >     )
> >
> > I'm not sure I got the syntax exactly right, but the idea is anything
> > that will iterate over a generator expression.  That at least gets rid
> > of the memory requirement to hold the throw-away list :-)
> 
> You could equivalently pass the generator to deque() with maxlen=0 - this
> consumes the iterator with constant memory usage.
> 
> We are of course firmly in the twilight zone at this point (although this
> can be a useful technique in general).

We've been in the twilight zone for a while.  That's when the fun 
starts.  But, somewhat more seriously, I wonder what, exactly, it is 
that freaks people out about:

>>>> [(new_songs if s.is_new() else old_songs).append(s) for s in songs]

Clearly, it's not the fact that it build and immediately discards a 
list, because that concern is addressed with the generator hack, and I 
think everybody (myself included) agrees that's just horrible.

Or, is it the use of the conditional to create the target for append()?  
Would people be as horrified if I wrote:

for s in songs:
    (new_songs if s.is_new() else old_songs).append(s)

or even:

for s in songs:
    the_right_list = new_songs if s.is_new() else old_songs
    the_right_list.append(s)



More information about the Python-list mailing list