
tn.pablo at gmail
Jul 2, 2009, 9:40 PM
Post #9 of 35
(738 views)
Permalink
|
On Thu, Jul 2, 2009 at 23:34, Brad<schickb [at] gmail> wrote: > On Jul 2, 9:08Â pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote: >> Brad <schi...@gmail.com> writes: >> > On Jul 2, 8:14Â pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote: >> > > schickb <schi...@gmail.com> writes: >> > > > def split(seq, func=None): >> > > > Â Â if func is None: >> > > > Â Â Â Â func = bool >> > > > Â Â t, f = [], [] >> > > > Â Â for item in seq: >> > > > Â Â Â Â if func(item): >> > > > Â Â Â Â Â Â t.append(item) >> > > > Â Â Â Â else: >> > > > Â Â Â Â Â Â f.append(item) >> > > > Â Â return (t, f) >> >> > > untested: >> >> > > Â Â def split(seq, func=bool): >> > > Â Â Â xs = zip(seq, itertools.imap(func, seq)) >> > > Â Â Â t = list(x for (x,y) in xs if y) >> > > Â Â Â f = list(x for (x,y) in xs if not y) >> > > Â Â Â return (t, f) >> >> > In my testing that is 3.5x slower than the original solution (and less >> > clear imo). I fixed my version to take a bool default. Either way, I'm >> > not really looking for additional ways to do this in Python unless >> > I've totally missed something. What I am considering is writing it in >> > C, much like filter. >> >> I'm a little skeptical that the C version will help much, if it's >> evaluating a python function at every list element. > > Perhaps true, but it would be a nice convenience (for me) as a built- > in written in either Python or C. Although the default case of a bool > function would surely be faster. > >> Here's a variant of your version: >> >> Â def split(seq, func=bool): >> Â Â Â t, f = [], [] >> Â Â Â ta, fa = t.append, f.append >> Â Â Â for item in seq: >> Â Â Â Â Â (ta if func(item) else fa)(item) >> Â Â Â return (t, f) >> >> This avoids some dict lookups and copying. Â I wonder if that helps >> significantly. > > Faster, but in tests of a few short sequences only 1% so. > > -Brad > -- > http://mail.python.org/mailman/listinfo/python-list > If it is speed that we are after, it's my understanding that map and filter are faster than iterating with the for statement (and also faster than list comprehensions). So here is a rewrite: def split(seq, func=bool): t = filter(func, seq) f = filter(lambda x: not func(x), seq) return list(t), list(f) The lambda thing is kinda ugly, but I can't think of anything else. Also, is it ok to return lists? Py3k saw a lot of APIs changed to return iterables instead of lists, so maybe my function should have 'return t, f' as it's last statement. -- Pablo Torres N. -- http://mail.python.org/mailman/listinfo/python-list
|