On Tue, Jun 11, 2013 at 6:34 AM, Roy Smith <r...@panix.com> wrote:
> new_songs = [s for s in songs if s.is_new()]
> old_songs = [s for s in songs if not s.is_new()]

Hmm. Would this serve?

old_songs = songs[:]
new_songs = [songs.remove(s) or s for s in songs if s.is_new()]

Python doesn't, AFAIK, have a "destructive remove and return"
operation, and del is a statement rather than an expression/operator,
but maybe this basic idea could be refined into something more useful.
It guarantees to call is_new only once per song.

The iterator version strikes my fancy. Maybe this isn't of use to you,
but I'm going to try my hand at making one anyway.

>>> def iterpartition(pred,it):
        """Partition an iterable based on a predicate.

        Returns two iterables, for those with pred False and those True."""
        falses,trues=[],[]
        it=iter(it)
        def get_false():
                while True:
                        if falses: yield falses.pop(0)
                        else:
                                while True:
                                        val=next(it)
                                        if pred(val): trues.append(val)
                                        else: break
                                yield val
        def get_true():
                while True:
                        if trues: yield trues.pop(0)
                        else:
                                while True:
                                        val=next(it)
                                        if not pred(val): falses.append(val)
                                        else: break
                                yield val
        return get_false(),get_true()
>>> f,t=iterpartition(lambda x: x%3,range(100000000))
>>> next(t)
1
>>> next(t)
2
>>> next(t)
4
>>> next(t)
5
>>> next(f)
0
>>> next(f)
3
>>> next(f)
6
>>> next(f)
9
>>> next(f)
12
>>> next(t)
7
>>> next(t)
8

Ha. :) Useless but fun.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to