Verständnis Frage (if-else) oder (try-except)

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.
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 12:46

Hallo
Folgendes Szenario
Ich habe ein Dictionary mit folgenden Schlüssel/Wert Paaren(Dienstnummer:Stunden)

Code: Alles auswählen

d = {"1001":7.8,"1002":5.4,"1003":6.5}
eine liste mit folgendem Inhalt(Dienstnummern)

Code: Alles auswählen

l = ["1001","1002","1004"]
und eine Variable S für Stunden die anfangs auf 0 steht

Code: Alles auswählen

s = 0.0
Nun sieht mein Code so aus:

Code: Alles auswählen

for i in l:
    if i in d:
        s += d[i]
else:
    print "Dienstnummer: %s existiert nicht"% i
Wo liegt der Unterschied hierzu

Code: Alles auswählen

try:
    for i in l:
        s += d[i]
except Keyerror:
    print "Dienstnummer: %s existiert nicht"% i
im Bezug auf die Fehlerbehandlung.

Das Ergebnis im Programm ist für mich(auf den ersten Blick)
das selbe.
Hoffe auf Erleuchtung :)

Gruß....busfahrer
Alles wird gut ;-)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Samstag 11. Oktober 2008, 12:56

Ersetze l durch

Code: Alles auswählen

l = ["1001","1002","1004","1005"]
und lass dein Programm damit mal laufen, evtl. kommst du ja so dahinter was da anders ist.

btw: Außerdem hast du da noch einen Einrückungsfehler, das was du da hast ist ein for-else und kein if-else. Die Doku sollte dir da weiterhelfen.
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

Samstag 11. Oktober 2008, 13:01

hallo!

wenn ein key in einem dictionary nicht existiert, wird ein 'KeyError' ausgeloest.

beispiel:

Code: Alles auswählen

>>> d = {"a":10, "b":80, "c":1}
>>> d["a"]
10
>>> d["x"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'x'
achja, und so muss dein code aussehen:

Code: Alles auswählen

for i in l:
    if i in d:
        s += d[i]
    else:
        print "Dienstnummer: %s existiert nicht"% i
oder, mit fehlerbehandlung:

Code: Alles auswählen

try:
    for i in l:
        s += d[i]
except Keyerror:
    print "Dienstnummer %s existiert nicht" % i
mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 13:20

Hi
btw: Außerdem hast du da noch einen Einrückungsfehler, das was du da hast ist ein for-else und kein if-else. Die Doku sollte dir da weiterhelfen.
Hab den Fehler nur hier beim Posten ins Forum gemacht.Im Programm
ist alles richtig eingerückt.

Habe festgestellt das bei der Variante mit if-else der Fehler ausgegeben wird,aber es wird über die komplette Liste durch iteriert.

Bei der Variante mit try-except wird der Fehler ausgegeben und die Iteration über die Liste an der Stelle abgebrochen.

Somit sollte Variante 2 speicherschonender sein.
Liege ich da mit meiner Annahme richtig?

Gruß....busfahrer
Alles wird gut ;-)
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

Samstag 11. Oktober 2008, 13:43

hallo busfahrer!

du musst doch wissen, was du willst.
wenn er bei einem nicht-vorhandenen key abbrechen soll, nimm die variante mit try/except.
wenn er weitermachen soll, dann nimm die mit if/else.
es ist nicht wirklich speicherschonender. dein float 's' wird dann eben nur groeßer ^^ aber das soll es ja - du willst doch alle stunden zusammenziehen.

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Benutzeravatar
snafu
User
Beiträge: 5465
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Samstag 11. Oktober 2008, 13:44

"i" finde ich an dieser Stelle sehr verwirrend, da man einen Zähler erwartet (z.B. den Index). Passender wäre wohl "elem". Oder gleich so:

Code: Alles auswählen

import sys

book_of_hours = {"1001":7.8,"1002":5.4,"1003":6.5}
id_numbers = ["1001","1002","1004"]
for id_nr in id_numbers:
    try:
        hours += book_of_hours[id_nr]
    except KeyError:
        print >> sys.stderr, id_nr, "does not exist"
Zuletzt geändert von snafu am Samstag 11. Oktober 2008, 13:50, insgesamt 2-mal geändert.
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Samstag 11. Oktober 2008, 13:47

Wenn dir die Dienstnummern egal sind kannst du auch mit

Code: Alles auswählen

for hour in d.itervalues():
    s += hour
arbeiten.

Unabhängig davon: Mach dir das Leben einfacher und benutze sprechende Namen.
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 14:10

@roschi
du musst doch wissen, was du willst.
Natürlich weiss ich was ich will.Mir hatte sich nur zuerst der
Unterschied zwischen beiden Varianten nicht erschlossen.
Bin nun Dank euch wieder etwas schlauer :)

Da ich die Dienstnummer im Textfenster eh von falsch in
richtig ändern muß und beim erneuten Berechnen über
die komlette Liste neu iteriert wird,werde ich mich für
Variante 2(try-except) entscheiden.

@snafu
vielen Dank für deinen Verbesserungsvorschlag


Gruß....busfahrer
Alles wird gut ;-)
Benutzeravatar
snafu
User
Beiträge: 5465
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Samstag 11. Oktober 2008, 14:35

Deine try-except-Variante umschliesst übrigens den kompletten Versuch. Das heißt: Sobald ein KeyError geworfen wird, bricht er ab und zeigt deine Fehlermeldung an. Bei meiner Variante wird der try-except-Block für jedes Element aus der Dienstnummernliste ausgeführt, was bedeutet, dass alle nicht existierenden Nummern gemeldet werden und halt auch alle Nummern, die existieren, zu den Gesamtstunden addiert werden (unabhängig von möglichen KeyErrors).
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 17:45

@snafu
Bei meiner Variante wird der try-except-Block für jedes Element aus der Dienstnummernliste ausgeführt, was bedeutet, dass alle nicht existierenden Nummern gemeldet werden
Habe die GUI für mein Prog mit Tkinter bzw. Tix geschrieben.
Schaffe es aber leider nicht,deine Variante in einem Textfenster
auszugeben.Könntest du mir vielleicht noch einen dezenten
Hinweis geben ob das überhaupt geht.Wenn ja wäre ich schon froh,
wenn du mich in die richtige Richtung schubsen würdest :)


Gruß....busfahrer
Alles wird gut ;-)
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Samstag 11. Oktober 2008, 18:00

snafu schreibt in StandardError.

Da muss aber nicht ran. Du kannst stattdessen ein Label in dein GUI aufnehmen und dessen Text in der except-Suite auf

Code: Alles auswählen

"%s does not exist" % id_nr
ändern.

Vielleicht solltest du noch ein paar Worte dazu verlieren wie das ganze denn ablaufen soll, dann kann man dir auch besser helfen ;)
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 18:38

Hallo
also hier mal das relevante Stück Code

Code: Alles auswählen

def ergebnis(self):
        self.erg_dz_entry.delete(0, tx.END)
        self.erg_sm_entry.delete(0, tx.END)
        self.std_kto_entry.delete(0, tx.END)
        self.ges_std = 0.0
        self.std_kto = 0.0
        self.dienstplan = open("/home/thomas/skripte/dienstplan.bin", "rb")
        self.dienste = pickle.load(self.dienstplan)
        self.dienstplan.close()
        self.dienstnummern = self.fenster.get(1.0, tx.END)
        self.dienstnummern = self.dienstnummern.strip().split(",")
        try:
            for dienst in self.dienstnummern:
                self.ges_std += self.dienste[dienst]
                self.std_kto += self.dienste[dienst] - 7.8666666667
        except KeyError:
                self.fenster.insert(tx.END, "\nDienstnr.:%s existiert nicht"% dienst)
Jetzt ist es ja im Moment so das bei der Exception nur die erste
falsche Dienstnummer ausgegeben wird,egal wieviele es tatsächlich
sind.Ich hätte aber gerne,wenn möglich,das alle falschen
Dienstnummern ausgegeben werden.
Hoffe das Codesnippet hilft.

Gruß....busfahrer
Alles wird gut ;-)
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Samstag 11. Oktober 2008, 19:07

Das ist ganz klar, dass das nur die erste falsche Dienstnummer ist ;) Darauf haben dich snafu und roschi aber auch hingewiesen.

Code: Alles auswählen

if key not in d.keys():
    errorlist.append(key)
else:
    print d[key]
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Samstag 11. Oktober 2008, 21:11

Habs nun zu meiner Zufriedenheit hin bekommen :D

Vielen Dank noch mal an alle

Gruß....busfahrer
Alles wird gut ;-)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Samstag 11. Oktober 2008, 21:15

cofi hat geschrieben:

Code: Alles auswählen

if key not in d.keys():
Das heißt

Code: Alles auswählen

if key not in d:
.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten