2016-04-27 16 views
2

Mit fmin_slsqp, ichin Python

ieqcons : list, optional 

A list of functions of length n such that ieqcons[j](x,*args) >= 0.0 in a successfully optimized problem. 

zu bieten haben, da mein Problem recht groß ist, ist die einfache Möglichkeit, sie explizit zu schreiben, funktioniert nicht.

def f1(x,arg1,arg2): 
    ... 
def f2(x,arg1,arg2): 
    ... 
... 

list_func = [f1,f2,...] 

Es ist diese Frage, die dynamic and anonymous functions in Python und die meisten der Antwort-Adressen gehen um den Code als String Parsen, die völlig unnötig scheint und kompliziert Vergehen der Argumente der Funktion. Die Art der Constrains-Liste besteht darin, dass ein einzelner Parameter (der Index z. B.) die Funktion eindeutig identifizieren kann, aber alle Funktionen in der Liste die gleichen Argumente erhalten und es nicht möglich ist, basierend auf übergebenen Argumenten zu unterscheiden.

Eine Konstruktion dieser Form wäre ausreichend und schmerzlos

def f(x,arg1,arg2,i): 
    # return value based on i 
    # e.g. # for constrain of form x[i]>=arg1[i] the funct is: 
    #  return x[i]-arg1[i] 

i = 1 
f1 = lambda x,arg1,arg2 : f(x,arg1,arg2,i) 
i = 2 
f2 = lambda x,arg1,arg2 : f(x,arg1,arg2,i) 

Aufruf f1 und f2 kehrt die gleichen Funktionen für i=2

Allerdings kann ich keine Lösung finden i endgültig in der Funktionsdefinition zu machen oder beschränken Sie ihren Umfang, Sichtbarkeit auf eine bestimmte Lambda-Funktion.

Als Bemerkung hat i eine Variable bleiben, da die endgültige Lösung wie

list_f =[] 
for i in range(0,num_cons): 
    list_f.append(lambda x,arg1,arg2 : f(x,arg1,arg2,i)) 

aussehen würde Wie kann ich dieses Problem lösen oder gibt es eine einfachere und kluge Weise, mein Ziel zu erreichen?

Antwort

2

Von dem, was ich verstehe, können Sie es functools.partial mit lösen:

from functools import partial 

list_f = [partial(f, i=i) for i in range(0, num_cons)] 

Sie weitere Informationen über lambda vs partial finden Sie hier:

+0

Vielen Dank ... es hat wie erwartet funktioniert –

1

Der Grund, seine funktioniert nicht wie erwartet, wenn Sie einen Lambda-Ausdruck schreiben, ruft er die Funktion nicht auf; Es wird aufgerufen, wenn Sie den Ausdruck auswerten.

Also, wenn Sie es bewerten, ist der Wert i 2, daher die gleichen Ergebnisse.

glaube ich, was Sie brauchen, ist functools.partial, wie folgt aus:

from functools import partial 

func_call_map = {i: partial(f, i=i) for i in [some range]} 

# Get result for i = 4 
ret_value = func_call_map[4](other, args, here) 
+0

Vielen Dank. Es macht total Sinn das Verhalten jetzt und "teilweise" macht den Job –

1

Nach @alecxe Link auf Python: Why is functools.partial necessary? und die Erklärung in den Kommentaren der eine der Antworten zur Verfügung gestellt, die späte Bindung (lazy evaluation) zu vermeiden erklärt @BurhanKhalid, müßte der Code geändert werden, wie

i = 1 
f1 = lambda x,arg1,arg2,n_i=i : f(x,arg1,arg2,n_i) 
i = 2 
f2 = lambda x,arg1,arg2,n_i=i : f(x,arg1,arg2,n_i) 

Aber mit functions.partial folgt bietet eine elegante Lösung.