[BangPypers] which is better solution of the question

Anand Balachandran Pillai abpillai at gmail.com
Wed Jun 17 08:29:05 CEST 2009


On Wed, Jun 17, 2009 at 12:01 AM, Jeff Rush <jeff at taupro.com> wrote:

> Abhishek Tiwari wrote:
> >
> > *Ans. 1*
> >
> > values, items = list(zip(*sorted(zip(values,items), reverse=True)))
> >
> > *Ans. 2*
> > new_values = sorted(values, reverse=True)
> > new_items = [items[x] for x in map(values.index,new_values)]
> >
> > I would like to know which method is better and why?
>
> The first one is better because the second one has a bug. ;-)
>
> Because of the way the second one uses values.index, it assumes there is
> a unique mapping between items and values.  When a duplicate integer
> appears in values, the second solution returns the wrong answer.


Here is a 4th solution.

 [item[1] for item in sorted(zip(values, items))][-1::-1]

 If you are too lazy to write a timeit function, you can use my timeit
 wrapper script at ASPN cookbook.

 http://code.activestate.com/recipes/389767/

I timed all the solutions provided so far.

def f1(): list(zip(*sorted(zip(values,items), reverse=True)))

def f2():
    new_values = sorted(values, reverse=True); [items[x] for x
map(values.index,new_values)]

def f3():
    [item[1] for item in sorted(zip(values, items))][-1::-1]

def f4():
    d = dict(zip(items, values))
    new_items = sorted(items, key=d.__getitem__, reverse=True)

Here are the times printed in order of f1...f4 for 10,000 passes.

[anand at localhost python]$ python listsort.py
6.97 usec/pass
6.95 usec/pass
4.65 usec/pass
9.27 usec/pass

Don't use sorted(..., reverse=True), it is a killer in terms of time.
This is the reason why f4(...) does not work anywhere close to
what is expected out of a dict(...) solution and why f1(...) performs
much below par.

For example, let us change f4(...) to not to use sorted(..., reverse=True)

def f4():
    d = dict(zip(items, values))
    new_items = sorted(items, key=d.__getitem__)[-1::-1]

The performance improves a bit,

[anand at localhost python]$ python listsort.py
7.06 usec/pass
7.04 usec/pass
4.61 usec/pass
9.04 usec/pass

To see the real effect of sorted(..., reverse=True), let us modify f3(...)
to
 use it instead of reversing the list at the end.


def f3():
    [item[1] for item in sorted(zip(values, items), reverse=True)]

 [anand at localhost python]$ python listsort.py
7.19 usec/pass
7.13 usec/pass
6.39 usec/pass*
9.72 usec/pass

The function f3() slows down almost 1.3 times.

Don't use sorted(..., reverse=True). Instead reverse the list in place
by using reverse slicing of l[-1::-1], which is about 1.5 times faster.



>
> -Jeff
> _______________________________________________
> BangPypers mailing list
> BangPypers at python.org
> http://mail.python.org/mailman/listinfo/bangpypers
>



-- 
-Anand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/bangpypers/attachments/20090617/7c2cf5a7/attachment.htm>


More information about the BangPypers mailing list