Hallo,
ich habe folgendes Problem. Meiner Meinung nach benötige ich im Code generierte Variablen um mein Problem lösen zu können. Auf meiner Suche nach ähnlichen Problemen wurde ich immer auf Dictionarys hingewiesen, wüsste jedoch nicht, wie ich damit mein Problem lösen kann.
Problemstellung:
var0 = function()
var1 = function2(var0)
var2 = function2(var1)
...
var99 = function2(var98)
Auf die Funktionen function und function2 habe ich keinen Einfluss.
Ich habe derzeit im Code Strings erzeugt die 'var0', 'var1',...,'var99' heißen.
Was könnte ich machen, damit soetwas funktioniert.
variable( 'var1') = function2(variable('var0'))
Vielen Dank für eure Vorschläge.
TomTomTom
dynamisches erzeugen von Variablen durch Strings
@TomTomTom: Ich verweie hier mal auf Dictionaries. ``variable( 'var1') = irgendwas`` ist ja schon mal keine gültige Syntax. Aber das Beispiel ist *so* nahe an `variable` als Dictionary dran, dass ich nicht so ganz verstehe wie Du Dictionaries nicht als Lösung sehen kannst!?
Edit: Und falls die Variable tatsächlich von 0 an durchnummeriert wird, dann willst Du kein Wörterbuch sondern ganz einfach eine Liste.
Edit2:
Edit: Und falls die Variable tatsächlich von 0 an durchnummeriert wird, dann willst Du kein Wörterbuch sondern ganz einfach eine Liste.
Edit2:
Code: Alles auswählen
var = [function()]
for _ in xrange(99):
var.append(function2(var[-1]))
@TomTomTom: Mal davon abgesehen das man auch Funktionen in Datenstrukturen stecken kann, weil das letztendlich Objekte, also Werte, sind wie andere auch, ist das hier doch überhaupt nicht der Fall (solange `function()` und/oder `function2()` keine Funktionen als Rückgabewerte haben).
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@TomTomTom: Falls du deine Funktionen wie angedeutet in dieser Weise aufrufst:also so, dass jede Funktion einfach nur einen Wert in einen anderen transformiert, und dieser dann lediglich als Basis für die nächste Transformation dient und nicht anderweitig benutzt wird, dann möchtest du vielleicht Funktionskomposition:Ergebnis:
Das Programm oben ist äquivalent zu diesem hier:
Code: Alles auswählen
v0 = ...
v1 = f1(v0)
v2 = f2(v1)
v3 = f3(v2)
v4 = f4(v3)
v5 = f5(v4)
v6 = f6(v5)
...
Code: Alles auswählen
def compose(*fs):
def composed(x):
for f in fs:
x = f(x)
return x
return composed
def add3(v):
return v + 3
def mul2(v):
return v * 2
new_func = compose(add3, mul2, str, mul2, int, add3)
result = new_func(7)
print result
Code: Alles auswählen
2023
Code: Alles auswählen
v0 = 7
v1 = add3(v0)
v2 = mul2(v1)
v3 = str(v2)
v4 = mul2(v3)
v5 = int(v4)
v6 = add3(v5)
result = v6
In specifications, Murphy's Law supersedes Ohm's.
@pillmuncher: Ich glaube auf Basis der Art seiner Frage und wie er dort mit Python operiert, dass deine Lösung für ihn nicht praktisch nutzbar ist. Da schwirrt mir gerade selbst der Kopf und ich habe aktuell keine freie Zeit mich da einzuarbeiten. Wird so etwas praktisch irgendwo programmiert (Kontext, Aufgaben) oder ist das ein esoterisches Sprachkonstrukt???
@pixewakb: Funktionskomposition und so eine `compose()`-Funktion gehört in der oder ähnlicher Form in den Werkzeugkasten jeder funktionalen Programmiersprache. Dazu muss man eigentlich nur Closures verstanden haben, die auf jeden Fall zu den Grundlagen funktionaler Programmiersprachen gehören. Und falls das jetzt zu esoterisch klingen sollte: so eine Programmiersprache ist JavaScript. Also eine ziemlich verbreitete und praktisch eingesetzte Sprache.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@pixewakb: Ja, manchmal benutze ich sowas. Ich bemühe mich, es nicht zu übertreiben mit dem funktionalen Stil. Sonst kann ich gleich in Scheme oder Haskell programmieren. Im Fall von TomTomTom, sofern ich ihn richtig verstanden habe, bietet sich Funktionskomposition allerdings an.
Man könnte es auch so programmieren, vielleicht wird es dann deutlicher, wie es funktioniert:Zum Vergleich:
Andererseits hat compose() einige nützliche Eigenschaften. Nehmen wir an, wir haben folgende Definitionen:Damit haben wir bereits die Menge der einstelligen Python-Funktionen zum Monoid gemacht. Monoide kennt jeder, der in der Schule Mathematik hatte. Allerdings wurde es nicht Monoid genannt. Es wurde einfach als ein paar anscheinend unzusammenhängende Gesetze gelehrt. Hier das Assoziativgesetz für die Addition und die Multiplikation:Wenn man statt der Zeichen + und * die add() und mul() Funktionen aus dem operator Modul verwendet, dann sieht es so aus:Und hier zum Vergleich für einstellige Funktionen f, g, h:Und in der Pythonshell kann man es ausprobieren:
Aus der Mathematik kennt man auch neutrale Elemente. Für die Addition ist das die 0 und für die Multiplikation die 1. Dabei gelten diese Gesetze:Oder in funktionaler Schreibweise:Und für unsere einstelligen Funktionen gibt es sowas ebenso, da ist das neutrale Element identity():In der Pythonshell:Blöd ist jetzt nur, dass man mit compose_two() nur zwei Funktionen komponieren kann. Für drei Funktionen könnte man sich definieren:Und für vier, fünf, ... Funktionen kann man sich ebenfalls compose-Funktionen schreiben. Nun gibt es aber in Python die Möglichkeit, beliebig viele Argumente an eine Funktion zu übergeben:Solche Funktionen nennt man variadisch. Damit kann man nun eine allgemeine compose() Funktion schreiben:Womit wir wieder am Anfang wären.
Ich schrieb, dass diese Funktion einige nützliche Eigenschaften hat. Man kann damit zB. compose_xxx() und die Identitätsfunktion definieren:
Man könnte es auch so programmieren, vielleicht wird es dann deutlicher, wie es funktioniert:
Code: Alles auswählen
>>> value = 7
>>> for func in add3, mul2, str, mul2, int, add3:
... value = func(value)
...
>>> print value
2023
Code: Alles auswählen
>>> add3(7)
10
>>> mul2(10)
20
>>> str(20)
'20'
>>> mul2('20')
'2020'
>>> int('2020')
2020
>>> add3(2020)
2023
Code: Alles auswählen
def compose_two(f, g):
def composed_two(x):
y = f(x)
z = g(y)
return z
return composed_two
def identity(x):
return x
Code: Alles auswählen
a + (b + c) == (a + b) + c
a * (b * c) == (a * b) * c
Code: Alles auswählen
from operator import add, mul
add(a, add(b, c)) == add(add(a, b), c)
mul(a, mul(b, c)) == mul(mul(a, b), c)
Code: Alles auswählen
compose_two(f, compose_two(g, h)) == compose_two(compose_two(f, g), h)
Code: Alles auswählen
>>> def mul2(v):
... return v * 2
...
>>> def add3(v):
... return v + 3
...
>>> def sub5(v):
... return v - 5
...
>>> func1 = compose_two(compose_two(mul2, add3), sub5)
>>> func2 = compose_two(mul2, compose_two(add3, sub5))
>>> func1(12)
22
>>> func2(12)
22
>>> sub5(add3(mul2(12))) # zum Vergleich
22
Code: Alles auswählen
a + 0 == 0 + a == a
a * 1 == 1 * a == a
Code: Alles auswählen
add(a, 0) == add(0, a) == a
mul(a, 1) == mul(1, a) == a
Code: Alles auswählen
compose_two(f, identity) == compose_two(identity, f) == f
Code: Alles auswählen
>>> f1 = compose_two(add3, identity)
>>> f2 = compose_two(identity, add3)
>>> f1(12)
15
>>> f2(12)
15
>>> add3(12)
15
Code: Alles auswählen
def compose_three(f, g, h):
def composed_three(x):
y = f(x)
z = g(y)
u = h(z)
return u
return composed_three
Code: Alles auswählen
>>> def foo(*args):
... for a in args:
... print(a)
...
>>> foo(1, 2, 3)
1
2
3
>>> foo('hallo', 'huhu')
hallo
huhu
Code: Alles auswählen
def compose(*fs):
def composed(x):
for f in fs:
x = f(x)
return x
return composed
Ich schrieb, dass diese Funktion einige nützliche Eigenschaften hat. Man kann damit zB. compose_xxx() und die Identitätsfunktion definieren:
Code: Alles auswählen
>>> def compose_two(f, g):
... return compose(f, g)
...
>>> def compose_three(f, g, h):
... return compose(f, g, h)
...
>>> func = compose_three(mul2, add3, sub5)
>>> func(12)
22
>>> identity = compose()
>>> identity(12)
12
>>> identity('hallo')
'hallo'
In specifications, Murphy's Law supersedes Ohm's.
Moment mal. In der ursprünglichen Frage ging es nicht um Komposition verschiedener Funktionen, sondern schlicht um die wiederholte Anwendung ein und derselben Funktion; nur für den Anfangswert wird eine andere Funktion benutzt.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Das hatte ich tatsächlich überlesen. Dann ist die Antwort an TomTomTom natürlich: Wenn du die Zwischenwerte nicht brauchst, dann nimm eine Schleife.bb1898 hat geschrieben:Moment mal. In der ursprünglichen Frage ging es nicht um Komposition verschiedener Funktionen, sondern schlicht um die wiederholte Anwendung ein und derselben Funktion;
Code: Alles auswählen
value = function()
for _ in range(99):
value = function2(value)
In specifications, Murphy's Law supersedes Ohm's.
Vielen Dank für eure vielen Antworten.
Zur Klärung meines Beispiels, es ging um die Erstellung von mehreren Gui Elementen, die immer als einen Parameter ein Grundelement erwarteten auf dem das Neue aufgebaut werden sollte. Ich konnte es inzwischen mittels des Dictionaries lösen.
Gruß TomTomTom
Zur Klärung meines Beispiels, es ging um die Erstellung von mehreren Gui Elementen, die immer als einen Parameter ein Grundelement erwarteten auf dem das Neue aufgebaut werden sollte. Ich konnte es inzwischen mittels des Dictionaries lösen.
Gruß TomTomTom