Ich bin gerade auf ein interessantes Problem gestossen ...
Nehmen wir an, ich habe eine Liste L beliebiger Laenge, die in jedem Eintrag vier Gleitkommawerte enthaellt: Min, Max, delta und value (eine Zaehlvariable).
Nun moechte ich daraus ineinandergeschachtelte Forschleifen machen, in der form:
Das Problem ist: Man kann soetwas nicht hardcoden, da man nicht weiss, wie lang die liste ist, denn diese haengt unter Umstaenden vom Userinput ab. Und man kann auch keine Forschleife ueber Forschleifen laufen lassen, da diese ja ineinander geschachtelt werden muessen.
Das einzige, was mir zur Loesung einfaellt, waere eine Rekursion anzuwenden und in jedem Funktionsaufruf eine For-Schleife zu realisieren. Allerdings waere das in meinem Code etwas problematisch ... und auch vom Stack her sehr verschwenderisch.
Ich weiß nicht obs geht, aber vielleicht ist es ja ein Gedanklicher anstoß.
...
Das könnte funktionieren, allerdings fehlt noch ein Zurücksetzen von L[depth].value bei depth--.
EDIT: Ansonsten könntest du auch noch versuchen, aus den for-Schleifen Listen (oder in Python Generatoren) zu machen. Je nach Anwendung lässt sich vielleicht was damit anfangen....
Nun ja .. ich habs mittlerweile umstrukturiert und doch mit Rekursion gemacht.
Allerdings finde ich das Thema interessant genug, um es hier weiter zu verfolgen. Ist ja ohnehin nicht allzuviel los.
Worum es geht ...
In einem Inputfile bastel ich ueber Schluesselwoerter eine Modellfunktion zusammen, die von meheren nichtlinearen (P0 bis Pn) und meheren linearen (A0 bis Am) Parametern abhaengt.
Die nichtlinearen P Parameter (effektiv Achsen in hochdimensionalen Raeumen) werden dann nach Benutzervorgabe mit den Schleifen abgerastert. An jedem Punkt wird ueber die restlichen linearen Parameter A0 bis Am eine multilineare Optimierung durchgefuehrt und die Regressionsguete R2 bestimmt. Danach wird, um moeglichst das Globale Optimum im Parameterraum P zu finden vom Rasterpunkt mit bester Regressionsguete eine nichtlineare Optimierung ueber alle Parameter P0 bis Pn und A0 bis Am gemacht.
Da die Anzahl der Parameter ( m und n ) vom Inputfile abhaengt, weiss man vorher nicht, wieviele Schleifen ineinander zu schachteln sind. Zudem sind die Funktionen f als Klassen (mit einer vrtuellen Methode) vom selben Basistyp abgeleitet um maximale Erweiterbarkeit zu gewaehrleisten. Nicht alle Funktionen f brauchen alle Parameter P0 bis Pn (die meisten haben nur 1 oder 2 Parameter). Das ganze laeuft dann ueber einen Levenberg-Marquardt-Solver zur Ermittlung minimaler Fehlerquadrate (Regression) bezueglich einiger Messwerte. Die Funktionen f sind selbst hochkomplexe Berechnungen aus quantenchemischen Rechnungen.
Wie man sieht, wird der Code nicht einfach haeufig ausgefuehrt, sondern die Werte der Parameter haben schon eine Bewandnis.
Ich habe mir erlaubt Desmulators iterative Lösung umzuschreiben, denn im Moment ist sie vor lauter Tipp- und Logikfehlern weit davon entfernt, mit Inelukis for-Schleifen-Ansatz äquivalent zu sein. ^^
Falls der Wunsch besteht, werde ich die korrigierten Fehler angeben.
1. Das Inverse des Ausdrucks "a < b" ist nicht "a > b", sondern "a >= b". (Danke an DFYX für die Berichtigung.) Falls bei dir nämlich a und b gleich sind, wird der auskommentierte Code ausgeführt, in Lukis Ansatz wäre es nicht der Fall.
2. Die Zuweisung im Bedingungsblock der zweiten Verzweigung ist der erste Grund für eine unendlichen Schleife, da der Variable 'depth' immer ein konstanter Wert zugewiesen wird, der ungleich '-1' und für die Abbruchbedingung der Schleife genau dieser Wert ausschlaggebend ist. Die Zuweisung sieht zwar cool aus, ist aber in den meisten Fällen ein Programmierfehler, so wie in diesem Fall.
3. Die 'value's der Listenelemente werden zwar nach Mannis Bemerkung beim Rücksprung zurückgesetzt, es fehlt aber eine Initialisierung dieser vor der ersten Benutzung nach dem Eintreten in die Schleife. Kein gravierender, aber für einen Vergleich beider Ansätze dennoch wichtiger Punkt.
4. Dieser Fehler ist etwas subtiler, denn um die Fehlerstelle zu erkennen, muss man das Programm in Gedanken ablaufen lassen. Es reicht schon der einfachste Fall von einer Liste mit einem Element und dessen 'delta' größer als die Differenz seiner 'max' und 'min'. Beim Eintritt in die Schleife ist 'depth' gleich 0. Nun wird 'value' um 'delta' erhöht und ist damit größer als 'max', d.h. der if-Block der ersten Verzweigung wird ausgeführt und führt damit - neben einer, an dieser Stelle nebenläufigen Änderung an 'value' - zu einer Verringerung von 'depth' um eins. Jetzt müsste man annehmen, dass ein 'depth'-Wert von -1 zum Abbruch der Schleife führen muss, aber weit gefehlt: Die nächste Verzweigung testet, ob 'depth' dem letzten Element in der Liste entspricht (was nicht der Fall ist, denn -1 ist ungleich 0) und falls nicht, wird 'depth' um eins erhöht. Nun ist 'depth' wieder gleich 0 und der Schleifenblock zu Ende, was zum Test der Abbruchbedingung der Schleife führt: Ist 'depth' gleich -1? Oder: Ist 0 gleich -1? Nein. Kein Abbruch, die Schleife wird mit den gleichen Werten fortgesetzt, die schon beim Eintritt gegeben waren. Der zweite Grund für eine unendliche Schleife. Funktioniert genauso mit allen anderen 'delta'-Werten und Listengrößen.
Editierter Punkt 5: Bei Lukis for-Schleifen-Ansatz gibt es den Test, ob 'value' kleiner 'max' ist, schon vor dem Erhöhen von 'value' um 'delta'. Bei dir ist das nicht der Fall, so dass du immer wieder Ausführungen des auskommentierten Codes überspringst und alleine das schon keine Äquivalenz zulässt.
Die korrigierten Fehlerstellen und eine Umstrukturierung, um einige Stellen zu beseitigen, die ich als unglücklich gelöst empfand und die auch teilweise mit den obigen Fehlern zusammenhingen, ergibt dann den von mir geposteten Code.
Da die Idee hinter deiner Lösung ok war, fand ich es schade, dass es bei der Umsetzung so happerte, was mich schließlich zur Korrektur reizte.