Map with an extra parameter

M

ml1n

Hi,
I'm not really sure how to explain this so maybe some example code is
best. This code makes a list of objects by taking a list of ints and
combining them with a constant:

class foo:
def __init__(self):
self.a = 0
self.b = 0

def func(a,b):
f = new foo()
f.a = a
f.b = b
return f

constants = [1]*6
vars = [1,2,3,4,5,6]
objects = map(func,vars,constants)

In the real world I need to do this as quick as possible (without
resorting to c) and there are several constants. (The constant is only
constant to each list so I can't make it a default argument to func.)
My question is, can anyone think of a way to do this efficiently
without having to use the `dummy` list of constants and would it be
quicker?

M.
 
B

bearophileHUGS

This may be what you need:

class foo:
def __init__(self, a, b):
self.a = a
self.b = b

vars = [1,2,3,4,5,6]
objects = [foo(a, 1) for a in vars]


Note that in Python the new is expressed wit the () at the end:
f = new foo()

Bye,
bearophile
 
M

ml1n

This may be what you need:

class foo:
def __init__(self, a, b):
self.a = a
self.b = b

vars = [1,2,3,4,5,6]
objects = [foo(a, 1) for a in vars]


Note that in Python the new is expressed wit the () at the end:
f = new foo()

Bye,
bearophile

(Not sure if this group likes top or bottom posts, sorry)
Thanks for the reply,
In the interests of speed my thinking was that using map would move the
loop out of Python and into C, is that the case when using list
comprehension? I'd always thought it was just syntatic short hand for
a Python loop.

M.
 
B

bearophileHUGS

ml1n said:
In the interests of speed my thinking was that using map would move the
loop out of Python and into C, is that the case when using list
comprehension? I'd always thought it was just syntatic short hand for
a Python loop.

In Python the faster things are often the most simple.
You can time your code to see what's faster.
And even better you may try the simpler solution, and if the program
results too much slow with a profiling you can find the spots needing
improvements.

Bye,
bearophile
 
P

Paul Rubin

ml1n said:
In the interests of speed my thinking was that using map would move the
loop out of Python and into C, is that the case when using list
comprehension? I'd always thought it was just syntatic short hand for
a Python loop.

Best to run benchmarks, but I don't expect a huge difference between
any of them.
 
S

Simon Forman

ml1n said:
This may be what you need:

class foo:
def __init__(self, a, b):
self.a = a
self.b = b

vars = [1,2,3,4,5,6]
objects = [foo(a, 1) for a in vars]


Note that in Python the new is expressed wit the () at the end:
f = new foo()

Bye,
bearophile

(Not sure if this group likes top or bottom posts, sorry)
Thanks for the reply,
In the interests of speed my thinking was that using map would move the
loop out of Python and into C, is that the case when using list
comprehension? I'd always thought it was just syntatic short hand for
a Python loop.

M.

Your thinking is correct. :) Check out
http://groups.google.ca/group/comp.lang.python/msg/7a56cf1a052b9c5d
wherein Fredrik Lundh shows the difference by bytecode disassembly.

Peace,
~Simon

P.S. Bottom posts.
 
P

Peter Otten

ml1n said:
I'm not really sure how to explain this so maybe some example code is
best. This code makes a list of objects by taking a list of ints and
combining them with a constant:

class foo:
def __init__(self):
self.a = 0
self.b = 0

def func(a,b):
f = new foo()
f.a = a
f.b = b
return f

constants = [1]*6
vars = [1,2,3,4,5,6]
objects = map(func,vars,constants)

In the real world I need to do this as quick as possible (without
resorting to c) and there are several constants. (The constant is only
constant to each list so I can't make it a default argument to func.)
My question is, can anyone think of a way to do this efficiently
without having to use the `dummy` list of constants and would it be
quicker?

Here are two more ways to achieve what you want, but you have to time them
youself.
.... def __init__(self, a, b):
.... self.a = a
.... self.b = b
.... def __repr__(self):
.... return "Foo(a=%r, b=%r)" % (self.a, self.b)
....
constants = repeat(1)
vars = [1, 2, 3]
list(starmap(Foo, izip(vars, constants)))
[Foo(a=1, b=1), Foo(a=2, b=1), Foo(a=3, b=1)]

This requires Python 2.5:
[Foo(a=1, b=1), Foo(a=2, b=1), Foo(a=3, b=1)]


Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top