Pitone generare una tabella di ricerca di espressioni lambda

voti
0

Sto costruendo un gioco e, al fine di farlo funzionare, ho bisogno di generare un elenco di pre-costruito o pronti a chiamare espressioni. Sto cercando di fare questo con le espressioni lambda, ma sto correndo in un problema che genera la tabella di ricerca. Il codice che ho è simile al seguente:

import inspect

def test(*args):
    string = Test Function: 
    for i in args:
        string += str(i) +  
    print(string)

funct_list = []

# The problem is in this for loop
for i in range(20):
    funct_list.append(lambda: test(i, Hello World))

for i in funct_list:
    print(inspect.getsource(i))

L'output che ottengo è:

funct_list.append(lambda: test(i, Hello World))
funct_list.append(lambda: test(i, Hello World))
funct_list.append(lambda: test(i, Hello World))
funct_list.append(lambda: test(i, Hello World))
...

e ho bisogno di andare:

funct_list.append(lambda: test(1, Hello World))
funct_list.append(lambda: test(2, Hello World))
funct_list.append(lambda: test(3, Hello World))
funct_list.append(lambda: test(4, Hello World))
...

Ho provato quanto segue entrambi e né lavoro

for i in range(20):
    funct_list.append(lambda: test(i, Hello World))

for i in range(20):
    x = (i, Hello World)
    funct_list.append(lambda: test(*x))

La mia domanda è come si fa a generare elenchi di espressioni lambda con alcune delle variabili all'interno della espressione lambda già impostato.

È pubblicato 07/10/2016 alle 18:14
dall'utente
In altre lingue...                            


1 risposte

voti
2

Come altri hanno già detto, le chiusure di Python sono tardiva , il che significa che le variabili da un ambito esterno fa riferimento a una chiusura (in altre parole, le variabili chiuse sopra ) vengono ricercati al momento della chiusura si chiama e non al momento della definizione .

Nel tuo esempio, la chiusura in questione si forma quando il lambda riferimento alla variabile idal campo di applicazione al di fuori. Tuttavia, quando il lambda è chiamato più tardi, il ciclo ha già finito e lasciato la variabile icon il valore di 19.

Un facile, ma non particolarmente elegante soluzione è quella di utilizzare un argomento di default per il lambda:

for i in range(20):
    funct_list.append(lambda x=i: test(x, "Hello World"))

A differenza delle variabili di chiusura, gli argomenti di default sono legati all'inizio e quindi ottenere l'effetto desiderato di catturare il valore della variabile ial momento della definizione di lambda.

Un modo migliore è l'uso functools.partialche permette di applicare parzialmente alcuni argomenti della funzione, "fissare" loro di un certo valore:

from functools import partial

for i in range(20):
    funct_list.append(partial(lambda x: test(x, "Hello World"), i))
Risposto il 07/10/2016 a 18:19
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more