help with list comprehension

George Sakkis george.sakkis at gmail.com
Fri May 2 01:50:21 EDT 2008


On May 1, 11:46 pm, Carsten Haese <carsten.ha... at gmail.com> wrote:
> Yves Dorfsman wrote:
>
> > In the following script, m1() and m2() work fine. I am assuming m2() is
> > faster although I haven't checked that (loops through the list twice
> > instead of once).
>
> Well, let's check it:
>
> $ python -m timeit -s "import x" "x.m1()"
> 100000 loops, best of 3: 6.43 usec per loop
>
> $ python -m timeit -s "import x" "x.m2()"
> 100000 loops, best of 3: 8.34 usec per loop
>
> As it turns out, m1 is faster than m2. The reason is that list
> comprehensions do the loop in C, whereas the for-append pattern does the
> loop on the Python level.
>
>
>
> > Now what I am trying to do is something like m3(). As currently written
> > it does not work, and I have tried different ways, but I haven't managed
> > to make it work.
>
> > Is there a possibility ? Or is m2() the optimum ?
>
> > [...]
> > def m1():
> >   colours = [ e['colour'] for e in l ]
> >   nums    = [ e['num']    for e in l ]
>
> > def m2():
> >   colours = []
> >   nums    = []
> >   for e in l:
> >     colours.append(e['colour'])
> >     nums.append(e['num'])
>
> > #def m3():
> > #  colours, nums = [ e['colour'], e['num'] for e in l ]
>
> m3 doesn't work because you're building a list of 10 color/number pairs
> that you're trying to unpack that into just two names. The working
> "derivative" of m3 is m1, which is the most natural, fastest and
> clearest solution to your problem.

Another alternative is:

from operator import itemgetter

def m3():
    colours, nums = zip(*map(itemgetter('colour','num'), l))

It's slower than m1() but faster than m2(); it's also the most
concise, especially if you extract more than two keys.

George



More information about the Python-list mailing list