About lambda.

X

Xin Wang

Some c++ guru said c++ is hard to learn but easy to
use. Is python easy for both aspect? I found lot's of
confused in coding.

#code
from Tkinter import *

def on_click(m):
print m
def lamb_on_click(m):
return lambda : on_click(m)
root = Tk()
btns = ['0', '1', '2', '3']
for n in btns:
b = Button(root, text=n, command=lamb_on_click(n))
#Ok!
b.pack()
root.mainloop()
#

Or,

#code
....
b = Button(root, text=n, command=lambda x=n:
click(x)) #Ok!
....
#

The code above works well too, but follow is NOT! WHY?

#code
....
b = Button(root, text=n, command=lambda :
on_click(n))
....
#

Whichever button be clicked, this only print '3'.

Keyword 'lambda' is just like a macro in c or templete
in c++ or not?



_______________________________
Do you Yahoo!?
Declare Yourself - Register online to vote today!
http://vote.yahoo.com
 
P

Peter Otten

Xin said:
Some c++ guru said c++ is hard to learn but easy to
use. Is python easy for both aspect? I found lot's of
confused in coding.

#code
from Tkinter import *

def on_click(m):
print m
def lamb_on_click(m):
return lambda : on_click(m)
root = Tk()
btns = ['0', '1', '2', '3']
for n in btns:
b = Button(root, text=n, command=lamb_on_click(n))
#Ok!
b.pack()
root.mainloop()
#

Or,

#code
...
b = Button(root, text=n, command=lambda x=n:
click(x)) #Ok!
...
#

The code above works well too, but follow is NOT! WHY?

#code
...
b = Button(root, text=n, command=lambda :
on_click(n))
...
#

Whichever button be clicked, this only print '3'.

Keyword 'lambda' is just like a macro in c or templete
in c++ or not?

Your problem has nothing to do with lambda.

f = lambda args: expr

is just another way to write

def f(args): return expr

You are rather fighting with scopes.
.... def f(): print i
.... funcs.append(f)
........
2
2
2

Here the functions f as defined in the for loop refer to the global name
'i', which is is bound to 2 by the time f is called.
There are various remedies, the simplest probably being
.... def f(i=i): print i
.... funcs.append(f)
........
0
1
2

Here the parameter i is set to default to the value the global i is bound
to. After this is done further rebindings of the global variable don't
affect that default value. When the function is called without parameter,
it prints the default value of its parameter i instead of the global i.

Another option is to define a factory function:
.... def f(): print i
.... return f
....
.... funcs.append(make_f(i))
........
0
1
2

This introduces another scope every time make_f() is called to which the i
inside f() refers.

Finally you can write a class with callable instances:
.... def __init__(self, i): self.i = i
.... def __call__(self): print self.i
....
.... funcs.append(F(i))
........
0
1
2

Any state is kept in the instance. This variant would be overkill in your
example but has the benefit that you can easily modify the state, e. g. you
could increment self.i every time the instance is called and factor out
functionality in helper methods for larger problems.

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

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,602
Members
45,182
Latest member
BettinaPol

Latest Threads

Top