if and for vernetzen

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
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Mich würde es interessieren wie man diese Struktur vereinfachen kann, habe jetzt schon einiges durchprobiert, aber es funktioniert nicht so recht.
die checks sind checkboxen und das if ist den anderen beiden übergeordnet.
info_for_click ist eine gezippte Liste und die andere if-Struktur checkt, ob die Elemente, die zuvor gewählt wurden, in der Liste vorhanden sind..

Code: Alles auswählen

if check4 == 0 and check3 == 1:
                    for Q_out, fieldreal_out, Number_out, Energy_out in info_for_click:
                        if Q_out == Q_chosen and Number_out == Number_chosen and Energy_out == Energy_chosen:
Vielen Dank im Vorraus,
Peter
BlackJack

@peter99: Es sieht so aus als wenn eine Liste die falsche Datenstruktur ist, wenn da linear gesucht werden muss. Da möchte man eigentlich eine Abbildung von den drei Werten nach denen gesucht wird auf den Wert denn dann verarbeitet wird haben. Entweder direkt auf den Wert, oder auf eine Liste von Werten falls es mehrere Treffer in `info_for_click` geben kann.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Ich habe darüber nachgedacht, was du gesagt hast und mir ist nicht ganz klar wie man das in Python durchführen kann.
Das Problem ist, dass info_for_click diese Struktur haben muss, da sie mehrmals im code verwendet wird, also würde ich diese Struktur gerne beibehalten.
Ich dachte, ich könne das Problem umgehen, aber ich möchte einen Wert returnen, was mit der Struktur nicht möglich ist

Code: Alles auswählen

def set_field_cells(Q_chosen, Number_chosen, Energy_chosen, info_field_calc):
    for Q_out, fieldreal_out, Number_out, Energy_out, Vebit_out in info_field_calc:
        if Q_out == Q_chosen and Number_out == Number_chosen and Energy_out == Energy_chosen:
            listfields = fieldreal_out
    return listfields
Das seltsame ist, dass der code manchmal funktioniert und manchmal nicht, daher dass es manchmal auf listfields später zugreifen kann(dh. dass die Funktion es manchmal returnt).
Wenn das statement irgendwie in eine Zeile zu bringen wäre, würde es glaube ich funktionieren.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Entschuldige, ich denke, ich habe von deiner Antwort nicht ganz das mitgenommen, was du mitgeben wolltest.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Was BlackJack (wahrscheinlich) meinte: Nutze ein Dictionary statt einer Liste und benutze als Schluessel das Tupel `(Q_chosen, Number_chosen, Energy_chosen)` (am besten noch mit PEP8 konformen Namen).

Damit wird deine Funktion zu:

Code: Alles auswählen

def set_field_cells(Q_chosen, Number_chosen, Energy_chosen, info_field_calc):
    return info_field_calc[Q_chosen, Number_chosen, Energy_chosen]
Oder anders gesagt: Ueberfluessig.

Sollte die Funktion tatsaechlich nur das machen, solltest du sie dringend umbenennen, denn es wird kein Wert gesetzt.
BlackJack

@peter99: Das Problem bei der Funktion ist, dass sie den Fall nicht abdeckt, dass das ``if`` auf *keinen* Eintrag zutrifft. Dann wird der Name listfields nicht an einen Wert gebunden und ist nach der Schleife nicht definiert. Die Zeile mit dem ``return`` führt dann zu einem `NameError` beziehungsweise zu einem `UnboundLocalError`.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

peter99 hat geschrieben:

Code: Alles auswählen

def set_field_cells(Q_chosen, Number_chosen, Energy_chosen, info_field_calc):
    for Q_out, fieldreal_out, Number_out, Energy_out, Vebit_out in info_field_calc:
        if Q_out == Q_chosen and Number_out == Number_chosen and Energy_out == Energy_chosen:
            listfields = fieldreal_out
    return listfields
Das seltsame ist, dass der code manchmal funktioniert und manchmal nicht, daher dass es manchmal auf listfields später zugreifen kann(dh. dass die Funktion es manchmal returnt).
BlackJack schrieb es ja bereits, aber ich drücke es nochmal mit anderen Worten aus: `listfields` wird durch deinen Code nur dann definiert, wenn in mindestens einem Schleifendurchlauf die `if`-Bedingung zutrifft. Andernfalls "kennt" Python nach Verlassen der `for`-Schleife den Namen `listfields` nicht, da der Code `listfields = fieldreal_out` dann nie ausgeführt wurde. Nun benutzt du `listfields` aber für dein `return`-Statement. Dies resultiert entsprechend in einem Fehler, falls es in keinem der vorherigen Schleifendurchläufe zur Definition von `listfields` (also: Zutreffen der Bedingung) kam.

Du kannst dieses Problem umgehen, wenn du vor Betreten der Schleife etwas wie `listfields = None` definierst. Dann würde beim Durchlaufen der `for`-Schleife entweder `listfields` einfach neu definiert werden mit einem `fieldreal_out` (Bedingung traf mindestens einmal zu) oder eben nicht (Bedingung traf nie zu). `listfields` würde bei letzterem Fall dann einfach den Wert `None` behalten und dieser würde entsprechend von deiner Funktion zurückgegeben werden.

Natürlich müsste an der Stelle, wo deine Funktion aufgerufen wurde, dann auch geprüft werden, ob `None` als Ergebnis des Funktionsaufrufes zurückgegeben wurde, denn mit `None` ist in der Regel kaum ein sinnvolles Weiterarbeiten möglich. Dies resultiert dann in eher unschönem Code und du könntest daher - vielleicht auch erst, wenn du etwas mehr Erfahrung mit Python hast - besser eine Exception in deiner Funktion werfen, statt `None` auszuliefern. Dies ist die moderne Art, dem Anwender zu zeigen: "Hey, hier stimmt etwas nicht".
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Vielen Dank!
Antworten