Einzelene Elemente von geschachtelten Listen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

Moin allemann,

ich habe aufgrund meine Masterthesis erstmalig mit Python zu tun, zuvor maximal mit C++/C#, aber das war auch eher rudimentär. Daher bin ich schnell an meinen Grenzen, wenn es um die Erstellung neuen Codes geht.
Nun habe ich schon ein anschauliches Stück fertig und theoretisch läuft auch immer mal alles.
Aber dann auch wieder nicht. Ich möchte für viele Paneele (Strömungslehre, Potentialtheorie) fünf bestimmte Werte ermitteln und diese in einer csv-Datei ausgeben lassen. Das war auch nicht so kompliziert. Diese Werte werden in einer Subliste (newpanel) gespeichert, die in einer Hauptliste (plotlist) ist. Ist im Code verständlicher. Für jedes nächste Paneel wird der Hauptliste mittels for-Schleife eine neue Subliste mit weiteren Berechnungswegen hinzugefügt.

An dieser Stelle die erste Frage, ist eine Hauptliste überhaupt nötig? Die konnte meine Werte bereits erfolgreich in ein Excel sehen, wenn ich sie direkt aus der for-Schleife für jedes Paneel plotten lassen. Der Grund warum ich davon wieder weg bin ist, dass die Datei riesig und unübersichtlich ist.

Daher habe ich die Liste dann erstmal nach Drücken sortiert.
Und möchte dann für jedes Element der Hauptliste den Prozentwert iterativ überprüfen, um mir nur bestimmte Werte plotten zu lassen und dann ja auch schon in der aufsteigenden Reihenfolge.

Aber dann steckt der Wurm drin. Ich komme mit der Übergabe der Listenelemente nicht zurecht. Weil mein Listenindex für die Iteration auch eine Liste ist.
Ich habe das Gefühl, das ist ein ganz banales Problem, aber ich sehe einfach nicht wie ich es löse. Jeder Tipp wäre super.

Über Namensgebung oder nicht besonders pythonische Anwendungen bitte nicht zu sehr auslassen, dass noch Verbesserungspotential besteht dürfte klar sein.

Code: Alles auswählen

for panel in self.BladePanels:
            
                newpanel = []            
                self.plotlist.append(newpanel)  #neue Subliste in die Hauptliste einfügen
            
                p_panx = panel.Pressure    #für alle Paneele den jeweiligen Druck ermitteln             
                newpanel.append(p_panx)       # den Druck an Position 0 der Sublise einfügen
               
                A_panx = panel.Area          #für alle Paneele den jeweiligen Flächeninhalt ermitteln  
                newpanel.append(A_panx)       # den Flächeninhalt an Position 1 der Sublise einfügen
            
                sigmax = (-p_panx)/(0.5*self.Density*(aRotationRate**2)*(self.RotorInfo.Diameter**2))  
                newpanel.append(sigmax)     # Sigma des Paneels an Position 2 der Sublise einfügen
        
                A_sum += A_panx
                newpanel.append(A_sum)       # die Summe der bisherigen Flächeninhalte an Position 3 der Sublise einfügen
            
                prozent = self.A_Blade/100 * A_sum
                newpanel.append(prozent)      # den Prozentanteil der Paneelfläche an Position 4 der Sublise einfügen
            
                self.plotlist.sort() # Die Tabelle nach der größe des Druck aufsteigend sortieren, bis hier alles prima!
          
        for elem in self.plotlist:     
            element = self.plotlist[elem]   # hier steckt der Fehler
            prozent =  int(element[4])      
            i = 0
            for i in min(prozent-i*0.03):
            
                Cav_Result = dict(Prozentanteil = prozent,
                           Paneeldruck = element[0], 
                           Paneelflaechen = element[1], 
                           SigmaX = element[3]
                           ) 
                # Write the result to file
                CavitationTable.writerow(Cav_Result)
                CavitationTable_File.flush() 
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

Kleiner Zusatz.

Die Fehlermeldung lautet wie folgt:

Code: Alles auswählen

Traceback (most recent call last):
  File "AllProp_Cav7.py", line 394, in <module>
    sci_analysis.calcSigmaIni(aRotationRate=Drehz)
  File "/data/tkt/user/home/LG0010/Documents/Tutorials/panMARE_Simulationen/Cavi                                                          tation/TVCI_inc_LG2.py", line 542, in calcSigmaIni
    element = self.plotlist[elem]
TypeError: list indices must be integers or slices, not list
Und nachdem ich ich daran gestern schon ewig rumgedoktort habe, hätte ich Überlegungen in den Raum zu werfen.
numpy.array und split und enumerate(liste)

Ich habe beides in anderen Beiträgen in relativ ähnlichen Zusammenhängen mehrfach gesehen, kann das aber auf meinen Fall nicht so richtig anwenden, weil ich dafür einfach nicht genug Basiswissen mitbringe zum aktuellen Zeitpunkt.

Und im Ursprungsbeitrag ist ein Schreibfehler: 'Berechnungswege' = Berechnungswerte!

Und dann noch meine besten Grüße und danke an alle die sich die Zeit nehmen den ganzen Bums zu lesen.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Vielleicht musst du nur

Code: Alles auswählen

for elem in self.plotlist:     
    element = self.plotlist[elem]   # hier steckt der Fehler
ersetzen durch

Code: Alles auswählen

for element in self.plotlist:
(ungetestet)
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

Moin bords0,
das kann glaube ich nicht hin haun. Die Laufvariabel würde dann im nächsten Schritt fix definiert werden, wodurch die Schleife hinfällig wird. Und ich kann dann nicht festlegen, was ich von der Hauptliste durchsuchen möchte.
Danke für deine Überlegung, aber einfach nur ersetzen funktioniert leider nicht.
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

also, mit :

Code: Alles auswählen

        for i, elem in enumerate(self.plotlist):     
            elem = self.plotlist[i]  
            prozent =  elem[4] 
scheint es zu klappen.
i zählt meine Sublisten und mit elem werden sie jeweils benannt um im nächsten Schritt darauf zugreifen zu können.
Ich hoffe jetzt, dass da auch das passiert was ich möchte und nicht nur irgend etwas wildes. Aber betrachten wir das erstmal als abgehakt.

Danach kommt nochmal eine for-Schleife, in der ich den jüngst gesuchten Wert 'prozent' mit einem Vergleichskriterium bemesse.

Code: Alles auswählen

            for j in min(prozent-j*0.03):
            
                Cav_Result = dict(Prozentanteil = prozent,
                           Paneeldruck = elem[0], 
                           Paneelflaechen = elem[1], 
                           SigmaX = elem[3]
                           ) 
                # Write the result to file
                CavitationTable.writerow(Cav_Result)
                CavitationTable_File.flush() 

Da 'prozent' jetzt ein float-Wert ist, geht das iterieren hier schon wieder nicht...
Wie kann ich das Problem umgehen?
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

pumabuma hat geschrieben: Mittwoch 9. Oktober 2019, 07:47 Moin bords0,
das kann glaube ich nicht hin haun. Die Laufvariabel würde dann im nächsten Schritt fix definiert werden, wodurch die Schleife hinfällig wird. Und ich kann dann nicht festlegen, was ich von der Hauptliste durchsuchen möchte.
Danke für deine Überlegung, aber einfach nur ersetzen funktioniert leider nicht.
Was meinst du mit Laufvariable? Und wieso wird sie im nächsten Schritt fix definiert? Die nächste Zeile wäre ja

Code: Alles auswählen

            prozent =  int(element[4])
Da wird doch nichts "fix definiert"?

Vielleicht solltest du dir nochmal anschauen, was eine for-Schleife in Python macht.
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

Wow! Ich hab mich auch vertan beim Ersetzen, hast Recht. Sehr peinlich, denn klappt natürlich. Aber cool, danke!!!
Ich hätte auch schwören können, dass ich das genau so schon versucht hatte, aber da hat es wohl noch an anderer Stelle gehakt, oh man.

Hast du auch noch ein Trick für das float-Problem?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was soll denn min(von_einer_zahl_obwohl_es_zwei_oder_mehr_sein_muessen) bewirken? Kann es sein, dass du da auf die naechstkleinere ganze Zahl raus willst? Das waere dann int(...). Doch dann kannst du immer noch nicht iterieren, da fehlt dir dann ein range.
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

ja sorry nochmal, das hat natürlich Erklärungsbedarf. Ich war mir mit dem Teil von Anfang an sehr unstimmig und habe schon befürchtet, dass das Mist ist.
Ziel ist es, die Prozentwerte, die am nächsten an 0,03 (0,06; 0,09; 0,12; etc) liegen zu finden. Um für diese dann jeweils meine csv.Liste mir zugehörigen Resultaten zu füllen.
Ich bin da auch schon dran, aber wie finde ich jetzt den nächsten Prozentwert, sodass ich auch gleichzeitig die anderen zugehörigen Werte parat habe? Ich verstricke mich dabei immer in Listen und verkompliziere das eher, also eine kompakte Lösung zu erreichen.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast for-Schleifen noch nicht verstanden. Dein Umgehungslösung mit enumerate ist unsinnig, weil `bords0` schon genau die richtige Lösung gezeigt hat. Das mit "kann glaube ich nicht hin haun" abzutun, ohne es probiert oder verstanden zu haben, ist stark.

Die erste for-Schleife über BladePanels ist auch schon komisch. Das `sort` muß auf jedenfall außerhalb der Schleife stehen. Wenn man 6 Werte hat, die alle etwas anderes bedeuten, dann benutzt man keine Liste und erst recht, füllt man diese Liste nacheinander mit append. Die Kommentare zeigen schon, dass die Liste das falsche Mittel sind.
Als Alternativen bieten sich NamedTuple, Wörterbücher oder eigene Klassen an. Da du eh später ein Wörterbuch hast,
hier mal mit Wörterbuch:

Code: Alles auswählen

plotlist = []
full_area = 0
for panel in self.BladePanels:
    full_area += panel.Area
    plotlist.append({
        "Paneeldruck": panel.Pressure,
        "Paneelflaechen": panel.Area,
        "SigmaX": (-p_panx)/(0.5*self.Density*(aRotationRate**2)*(self.RotorInfo.Diameter**2)),
        # "FullArea": full_area, scheint nicht gebraucht zu werden
        "Prozentanteil": self.A_Blade/100 * full_area,
    }
plotlist.sort(key=lambda p:p['Paneeldruck'])
for element in plotlist:
    rel_area =  int(element["Prozentanteil"])
    # was soll diese for-Schleife?
    # for i in min(prozent-i*0.03):
    # Write the result to file
    CavitationTable.writerow(element)
CavitationTable_File.flush()
Du hältst Dich nicht an die Namenskonvention, dass Variablennamen klein_mit_unterstrich geschrieben werden, das macht das Verstehen des Codes unnötig kompliziert. Was die for-Schleife mit min bewirken soll, habe ich immer noch nicht verstanden, zumal `i` ja gar nicht benutzt wird.
pumabuma
User
Beiträge: 10
Registriert: Dienstag 8. Oktober 2019, 12:57

okay, erstmal danke, die Sortierung sollte tatsächlich gar nicht in die Schleife, dass war ein Versehen und so auch nicht geplant.

Und den ersten Beitrag von bords0 hatte ich nicht einfach abgetan, nur im ersten Ansatz verkehrt umgesetzt und mich dafür auch entschuldigt. Wenn nicht deutlich genug: Tut mir Leid, dass ich den Tipp so schnell abgetan hatte.
Ich bin momentan auf diese Programmierung angewiesen, obwohl das leider nie wirklich Gegenstand meines Studiums war, daher kenne ich einfach nur ein paar Basis-befehle und auch Namenskonventionen muss man sich dann irgendwie antrainieren. Ist schon klar, dass da nicht immer die beste Lösung bei herauskommt, hatte ich auch eingangs vorgewarnt, weshalb ich die Art von Weise das jetzt zu bemängeln relativ scharf finde.

Aber um weiter sachlich und beim Thema zu bleiben, die Alternativen versuche ich direkt mal ausprobieren, ich will das ja schon lernen.

Über diese letzte Geschichte mit min, um den nähesten Wert zu finden, mache ich mir nochmal Gedanken, wenn der Rest sauber ist.
Antworten