Ich habe eine Übung in Python wie folgt:
Ein Polynom wird als Tupel von Koeffizienten angegeben, so dass die Potenzen durch die Indizes bestimmt werden, z. B.: (9,7,5) bedeutet 9 + 7 * x + 5 * x ^ 2
Schreiben Sie eine Funktion, um ihren Wert für ein gegebenes x zu berechnen
Da ich mich in letzter Zeit mit funktionaler Programmierung beschäftige, habe ich geschrieben
def evaluate1(poly, x):
coeff = 0
power = 1
return reduce(lambda accu,pair : accu + pair[coeff] * x**pair[power],
map(lambda x,y:(x,y), poly, range(len(poly))),
0)
was ich für unlesbar halte, schrieb ich
def evaluate2(poly, x):
power = 0
result = 1
return reduce(lambda accu,coeff : (accu[power]+1, accu[result] + coeff * x**accu[power]),
poly,
(0,0)
)[result]
Das ist mindestens genauso unlesbar, also schrieb ich
def evaluate3(poly, x):
return poly[0]+x*evaluate(poly[1:],x) if len(poly)>0 else 0
Das könnte weniger effizient sein (edit: Ich habe mich geirrt!), da es viele Multiplikationen anstelle von Potenzierung verwendet. Im Prinzip interessieren mich Messungen hier nicht (edit: Wie dumm von mir! Messen hätte auf mein Missverständnis hingewiesen!) und immer noch nicht so lesbar (wohl) wie die iterative Lösung:
def evaluate4(poly, x):
result = 0
for i in range(0,len(poly)):
result += poly[i] * x**i
return result
Gibt es eine rein funktionale Lösung, die so lesbar wie der Imperativ ist und deren Effizienz nahe kommt?
Zugegeben, eine Änderung der Repräsentation würde helfen, aber dies wurde durch die Übung gegeben.
Kann auch Haskell oder Lisp sein, nicht nur Python.
lambda
Vergleich zu Sprachen mit einer leichteren anonymen Syntaxfunktion notorisch hässlich, wenn Sie mit der Verwendung beginnen . Ein Teil davon trägt wahrscheinlich zum "unreinen" Aussehen bei.
for
, dass beispielsweise keine Schleifen verwendet werden) ein schlechtes Ziel in Python. Das vernünftige erneute Binden von Variablen und das Nicht-Mutieren von Objekten bietet Ihnen fast alle Vorteile und macht den Code unendlich lesbarer. Da Zahlenobjekte unveränderlich sind und nur zwei lokale Namen neu binden, erkennt Ihre "imperative" Lösung funktionale Programmiertugenden besser als jeder "streng reine" Python-Code.