469,270 Members | 1,120 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,270 developers. It's quick & easy.

help with list comprehension


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).

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 ?
Thanks.

#!/usr/bin/python

l = [ { 'colour': 'black', 'num': 0},
{ 'colour': 'brown', 'num': 1},
{ 'colour': 'red', 'num': 2},
{ 'colour': 'orange', 'num': 3},
{ 'colour': 'yellow', 'num': 4},
{ 'colour': 'green', 'num': 5},
{ 'colour': 'blue', 'num': 6},
{ 'colour': 'violet', 'num': 7},
{ 'colour': 'grey', 'num': 8},
{ 'colour': 'white', 'num': 9}
]

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 ]

--
Yves.
http://www.SollerS.ca
Jun 27 '08 #1
6 916
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.

HTH,

--
Carsten Haese
http://informixdb.sourceforge.net
Jun 27 '08 #2
On May 1, 8:01 pm, Yves Dorfsman <y...@zioup.comwrote:
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).

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 ?

Thanks.

#!/usr/bin/python

l = [ { 'colour': 'black', 'num': 0},
{ 'colour': 'brown', 'num': 1},
{ 'colour': 'red', 'num': 2},
{ 'colour': 'orange', 'num': 3},
{ 'colour': 'yellow', 'num': 4},
{ 'colour': 'green', 'num': 5},
{ 'colour': 'blue', 'num': 6},
{ 'colour': 'violet', 'num': 7},
{ 'colour': 'grey', 'num': 8},
{ 'colour': 'white', 'num': 9}
]

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 ]
Looks like m1 is the cleanest; if you really want to run list-
comprehension once, one possible way:
>>p = [ (e['colour'], e['num']) for e in l ]
import operator
map(operator.itemgetter(0), p)
['black', 'brown', 'red', 'orange', 'yellow', 'green', 'blue',
'violet', 'grey', 'white']
>>map(operator.itemgetter(1), p)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Karthik
--
Yves.http://www.SollerS.ca
Jun 27 '08 #3
On May 1, 11:46*pm, Carsten Haese <carsten.ha...@gmail.comwrote:
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
Jun 27 '08 #4
On May 1, 10:50 pm, George Sakkis <george.sak...@gmail.comwrote:
On May 1, 11:46 pm, Carsten Haese <carsten.ha...@gmail.comwrote:
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
Why deal with zip and unpacking? This seems more obvious to me:

colours, nums = map(itemgetter('colour'), l), map(itemgetter('num'),
l)

Matt
Jun 27 '08 #5
On May 2, 2:17*am, Matimus <mccre...@gmail.comwrote:
On May 1, 10:50 pm, George Sakkis <george.sak...@gmail.comwrote:
On May 1, 11:46 pm, Carsten Haese <carsten.ha...@gmail.comwrote:
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

Why deal with zip and unpacking?
DRY [1].

This seems more obvious to me:
>
colours, nums = map(itemgetter('colour'), l), map(itemgetter('num'),
l)
Maybe, but now extend it to three keys. And then four. And then... you
see my point.

George

[1] http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
Jun 27 '08 #6
George Sakkis wrote:
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.
Good you guys gave me some ideas, I've made m3() work:

def m3()
total = [ [e['colour'], e['num'], e['couleur']] for e in l ]
c,d,e = zip(*total)
return map(list, [c,d,e])

(I have to transform to lists, I need to transform them later on, so tuples
won't work).

Unfortunately the timing is inconsistant, the first time I run
python -m timeit 'import listcomp ; listcomp.m1()'

m1 is the fastest. But then if I run the test several times, they all seem
to be about the same time ; I'll have to try with a large list.

Now here is a question:
Is there any way to change my first line there for the list comp. to return
a list of lists rather than a list of tuples ?
Jun 27 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

23 posts views Thread by Fuzzyman | last post: by
35 posts views Thread by Moosebumps | last post: by
6 posts views Thread by jena | last post: by
18 posts views Thread by a | last post: by
4 posts views Thread by Gregory Guthrie | last post: by
4 posts views Thread by bullockbefriending bard | last post: by
11 posts views Thread by beginner | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.