2013-03-11 7 views
8

Python jest tak elastyczny, że mogę używać funkcji jako elementów list lub argumentów innych funkcji. Na przykład:Jak przekazać losową funkcję jako argument?

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

lub

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

Jednak to nie jest dla mnie jasne, w jaki sposób zrobić to samo z przypadkowych funkcji. Na przykład chcę użyć rozkładów Gaussa: [random.normalvariate(3.0, 2.0), random.normalvariate(1.0, 4.0)]. W tym przykładzie otrzymam stałą listę zawierającą dwa elementy. Ale to, co chcę uzyskać, to lista z przypadkowymi elementami. Jaki jest dobry sposób to zrobić w python?

+0

nie mógł zrozumieć, odpowiednio, szukasz zmiennej liczby argumentów? http://docs.python.org/2/tutorial/controlflow.html#arbitrary-argument-lists – Pheonix

Odpowiedz

8

Spróbuj z lambda funkcji:

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

widać różnicę z nawiasami. sin jest funkcja sin(x) jest zwrócona wartość tej funkcji. Jak nie można utworzyć funkcję bez nawiasów reprezentujących random.normalvariate(1.0, 4.0), musisz zdefiniować go jako funkcji lambda.

7

Zastosowanie functools.partial lub lambda

Są w zasadzie takie same:

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

Oboje są równoważne:

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

[_function, ...] 

partial jest bardziej elastyczny, daje znacznie lepszą kontrolę nad tworzeniem z _function i pozwala uniknąć bałaganu składni lambda.

Nawiasem mówiąc, było kilka controversions ponad lambda w społeczności Pythona, ale w końcu przyznał, że Guido finding a superior alternative to the lambda expression is "an impossible quest."

5

Należy użyć częściowy z 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]()