parameters to lambda's executed at run time.

W

wyleu

I'm trying to supply parameters to a function that is called at a
later time as in the code below:

llist = []

for item in range(5):
llist.append(lambda: func(item))

def func(item):
print item

for thing in llist:
thing()

which produces the result

IDLE 1.2.1<function <lambda> at 0xb716356c>
<function <lambda> at 0xb71635a4>
<function <lambda> at 0xb71635dc>
4
4
4
4
4

How can one allocate a different parameter to each instance of the
function rather than all of them getting the final value of the loop?
 
D

Diez B. Roggisch

wyleu said:
I'm trying to supply parameters to a function that is called at a
later time as in the code below:

llist = []

for item in range(5):
llist.append(lambda: func(item))

def func(item):
print item

for thing in llist:
thing()

which produces the result

IDLE 1.2.1<function <lambda> at 0xb716356c>
<function <lambda> at 0xb71635a4>
<function <lambda> at 0xb71635dc>
4
4
4
4
4

How can one allocate a different parameter to each instance of the
function rather than all of them getting the final value of the loop?

That's a FAQ. Python creates a closure for you that will retain the last
value bound. To prevent that, you need to create a named paramter like
this:

lambda item=item: func(item)

That will bind the current item value at the lambda creation time.

Diez
 
B

Boris Borcic

One way :
>>> from functools import partial
>>> def func(item) : print item
>>> llist = [partial(func,item) for item in range(5)]
>>> for thing in llist : thing()

0
1
2
3
4

I'm trying to supply parameters to a function that is called at a
later time as in the code below:

llist = []

for item in range(5):
llist.append(lambda: func(item))

def func(item):
print item

for thing in llist:
thing()

which produces the result

IDLE 1.2.1<function <lambda> at 0xb716356c>
<function <lambda> at 0xb71635a4>
<function <lambda> at 0xb71635dc>
4
4
4
4
4

How can one allocate a different parameter to each instance of the
function rather than all of them getting the final value of the loop?
 
M

Marco Mariani

Boris said:
One way :
from functools import partial
def func(item) : print item
llist = [partial(func,item) for item in range(5)]
for thing in llist : thing()

0
1
2
3
4

Another way:


class Func(object):
def __init__(self, item):
self.item = item
def __call__(self):
print self.item

llist = [Func(item) for item in range(5)]
for thing in llist: thing()
 
C

castironpi

wyleu said:
I'm trying to supply parameters to a function that is called at a
later time as in the code below:
llist = []
for item in range(5):
    llist.append(lambda: func(item))
def func(item):
    print item
for thing in llist:
    thing()
which produces the result
IDLE 1.2.1
<function <lambda> at 0xb716356c>
<function <lambda> at 0xb71635a4>
<function <lambda> at 0xb71635dc>


How can one allocate a different parameter to each instance of the
function rather than all of them getting the final value of the loop?

That's a FAQ. Python creates a closure for you that will retain the last
value bound. To prevent that, you need to create a named paramter like
this:

lambda item=item: func(item)

That will bind the current item value at the lambda creation time.

Diez- Hide quoted text -

- Show quoted text -

I am getting lambda creation-time bindings on 2.5.
g= [ lambda h= i: h for i in range( 10 ) ]
[ e( ) for e in g ]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
g= [ lambda: i for i in range( 10 ) ]
[ e( ) for e in g ]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
 

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,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top