2012-04-06 11 views
2

Also ich habe einen numerischen Wert und auf diese beiden Funktionen angewendet werden können.Erhalt der Reihenfolge der Funktionsimplementierung

Können sagen, ich habe eine Reihe 8.

Ich mag seinen Platz nehmen und dann ihr Protokoll oder zuerst das Protokoll und dann seinem Platz.

So sieht meine Funktion so etwas wie dieses

def transform(value, transformation_list): 
    # value is int, transformation_list = ["log",square"] or ["square","log"] 
# square function and log function 
return transformed value 

Nun, wenn das erste Argument der Transformationsliste „square“ ist und das zweite ist „log“, dann sollte es erste Platz ausführen und dann log

Aber wenn die erste Funktion in dieser Liste "log" und zweitens "Quadrat" ist, dann sollte es zuerst Log und dann Quadrat implementieren.

Ich möchte nicht, wenn: Sonst etwas wie es wird hässlich werden, wie ich weitere Transformationen hinzufügen Wie soll ich das gestalten.

+3

Ist es erforderlich, dass die Transformationsliste eine Liste von Strings ist? Sie könnten einfach eine Liste von Funktionen übergeben ('from Pfadimportprotokoll; def square (x): return x * x; transformieren (8, [log, square])'). – delnan

+0

können Sie es als Lösung schreiben und es ein wenig erklären? es muss nicht eine Liste sein .. ?? – Fraz

+1

Es ist wahrscheinlich keine Antwort, aber mein Punkt ist: Anstatt eine Liste von Strings zu übergeben, könnten Sie Dinge einfacher und erweiterbarer machen, indem Sie eine Liste von Funktionen übergeben. – delnan

Antwort

2

So etwas wie die folgenden funktionieren sollte:

import math 

func_dict = {'square': lambda x: x**2, 
      'cube': lambda x: x**3, 
      'log': math.log} 

def transform(value, transformation_list): 
    for func_name in transformation_list: 
     value = func_dict[func_name](value) 
    return value 

Zum Beispiel:

>>> transform(math.e, ['cube', 'log', 'square']) 
9.0 
+0

Perfekt :) Danke – Fraz

2

diese Verwendung recipe für Funktions Zusammensetzung (oder alternativ mit dem functional Modul) können Sie eine beliebige Liste zusammenstellen von Funktionen - keine Notwendigkeit, die Namen als Zeichenfolgen zu übergeben, übergeben Sie einfach die Funktionen:

class compose: 
    def __init__(self, f, g, *args, **kwargs): 
     self.f = f 
     self.g = g 
     self.pending = args[:] 
     self.kwargs = kwargs.copy() 
    def __call__(self, *args, **kwargs): 
     return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs) 

def transform(value, transformation_list, inverted=False): 
    lst = transformation_list if inverted else reversed(transformation_list) 
    return reduce(compose, lst)(value) 

Jetzt können Sie transform wie folgt aufrufen:

from math import * 
value = 2 
transformation_list = [sin, sqrt, log] 
transform(value, transformation_list) 
> -0.047541518047580299 

Und die oben wird log(sqrt(sin(2))) gleichwertig sein. Wenn Sie die Reihenfolge der Funktionsanwendung invertieren benötigen, beispielsweise sin(sqrt(log(2))), dann tut dies:

transform(value, transformation_list, inverted=True) 
> 0.73965300649866683 

Sie können aber auch Funktionen in-line definieren. Zum Beispiel würde das Beispiel von F.J so aussehen, wenn ich meine Implementierung verwende:

transform(e, [lambda x:x**3, log, lambda x:x**2]) 
> 9.0 
Verwandte Themen