Lambda click on the list and then call - the output is not as expected

All:

def a(p): 
    return p+1 

def gen(func, k=100): 
    l= [] 
    for x in range(k): 
       temp = ("%s_with_parameter_%s" %(func.__name__, x), lambda: func(x)) 
       # maybe this will be more clear to explain my quetion: 
       # i want to get list/dict which can bind self-defined string and function together 
       l.append(temp) 
    return l 

l = gen(a, 100) 

for x in range(len(l)): 
   l[x][1]()                

100
100
100
100
100
100
100
100

... I assume that the output will be printed 1 to 101, but it will display a list 100.

Can I get help for this snippet here?

Thank!

+3
source share
5 answers

As other answers note, lambdas use the last x value because they are closed above it and therefore see any changes made to it. The trick is to bind them to a value.

You can do this by writing them as

lambda x=x: func(x)

x, , p, , x - . , , , :

for x in range(len(l)):
   l[x][1]()

, , , .

, , "" :

lambda p, x=x: func(p, x)
+6

, gen() :

def gen(func, k=100):
    l= []
    for x in range(k):
       l.append(lambda x=x: func(x))
    return l

. , lambda x. x .

+3

, , .

def a(p):
    return p+1

def gen(func, k=100):
    l= []
    for x in range(k):
       l.append(lambda p: func(x))
    x = 77
    return l

l = gen(a, 100)

for x in range(len(l)):
   print l[x](10)

78 lx. , x , .

, , , - Haskell. python functools.partial . , . , .

import functools

def a(p):
    return p+1

def gen(func, k=100):
    l= []
    for x in range(k):
        l.append(functools.partial(func, x))
    return l

l = gen(a, 100)

for x in range(len(l)):
   print l[x]()

:

import functools

def a(p):
    return p+1

def gen(func, k=100):
    fn = lambda x, p: func(x)
    l= []
    for x in range(k):
        l.append(functools.partial(fn, x))
    return l

l = gen(a, 100)

for x in range(len(l)):
   print l[x](10)

. : -)

+2

, , , a(), , x ( 100), p ( ). , lambda "", .

, l[x](10) "": ( , )

lambda 10: func(100)
0

yield , , :

>>> def a(p):
...     return p+1
...
>>> def gen(func, k=100):
...     for x in range(k):
...         yield lambda :func(x)
...
>>> for item in gen(a, 100):
...     item()
...
1
2
3
4
(...)
100
>>>

, , 100 - :

>>> range(100)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 2
2, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 4
2, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 6
2, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 8
2, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>>

gen (a, 101), :

>>> for item in gen(a, 101):
...     item()
...
1
2
3
4
5
(...)
101
>>>
0

Source: https://habr.com/ru/post/1773597/


All Articles