2013-03-11 20 views
8

Python è così flessibile da poter utilizzare le funzioni come elementi di elenchi o argomenti di altre funzioni. Per esempio:Come passare una funzione casuale come argomento?

x = [sin, cos] 
y = s[0](3.14) # It returns sin(3.14) 

o

def func(f1, f2): 
    return f1(2.0) + f2(3.0) 

Tuttavia, non è chiaro per me come fare lo stesso con funzioni casuali. Ad esempio, voglio utilizzare le distribuzioni gaussiane: [random.normalvariate(3.0, 2.0), random.normalvariate(1.0, 4.0)]. In questo esempio otterrò una lista fissa contenente due elementi. Ma quello che voglio ottenere è una lista con elementi casuali. Qual è un buon modo per farlo in Python?

+0

non riusciva a capire correttamente, stai cercando un numero variabile di argomenti? http://docs.python.org/2/tutorial/controlflow.html#arbitrary-argument-lists – Pheonix

risposta

8

provare con lambda funzioni:

[lambda: random.normalvariate(3.0, 2.0), lambda: random.normalvariate(1.0, 4.0)] 

Si vede la differenza con parentesi. sin è una funzione, sin(x) è il valore restituito da questa funzione. Poiché non è possibile creare una funzione senza parentesi che rappresenta random.normalvariate(1.0, 4.0), è necessario definirla come funzione lambda.

7

Usa functools.partial o lambda

Quelli sono fondamentalmente gli stessi:

[lambda: normalvariate(3, 2), ...] 
# or 
[partial(normalvariate, 3, 2), ...] 

Entrambi sono equivalenti a:

def _function(): 
    return normalvariate(3, 2) 

[_function, ...] 

partial è più flessibile, ti dà molto migliore controllo sulla creazione di _function e consente di evitare l'ingombro della sintassi lambda.

A proposito, ci sono stati alcuni controversions oltre lambda nella comunità Python, ma alla fine ha ammesso che Guido finding a superior alternative to the lambda expression is "an impossible quest."

5

si dovrebbe usare parziale dal functools:

import functools 
arg_sets = [(3.0, 2.0), (1.0, 4.0)] 
myfuncs = [functools.partial(random.normalvariate, *args) for args in arg_sets] 
myfuncs[0]() 
Problemi correlati