Verschachtelte for-Schleifen 'verschönern'?

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
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Guten Morgen Forum,

ich habe folgenden Code der auch funktioniert:

Code: Alles auswählen

        if request.POST:
            for k, v in request.POST.items():
                if k.isdigit():
                    for article in articles:
                        if article.nr == int(k):
                            article.oldvalue = v

Allerdings kommt er mir sehr unpythonisch vor.

Gibt es da einen 'schöneren' Weg der das Ganze nicht unleserlicher macht?

Ich danke für etwaige Hilfe!


Gruß
Sparrow
BlackJack

@sparrow: Erste Frage wäre was das ``if`` am Anfang prüft – wenn es nur dazu da ist zu prüfen ob `POST` "nicht leer" ist, und nicht zum Beispiel auch das es nicht `None` ist, kann man es wahrscheinlich komplett weglassen.

Das hat vielleicht auch unnötigerweise quadratische Laufzeit. Da sollte man aus einer der beiden Schleifen ein Wörterbuch erstellen und die Schleifen dann nacheinander ablaufen lassen, statt sie zu verschachteln. Ungetestet:

Code: Alles auswählen

        if request.POST:
            nr2value = dict(
                (int(k), v) in request.POST.iteritems() if k.isdigit()
            )
            for article in articles:
                try:
                    article.oldvalue = nr2value[article.nr]
                except KeyError:
                    pass
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Danke für die Antwort BlackJack.

Ist es vorzuziehen die Exception zu fangen und nicht zu bahandeln oder vorher auf das vorhanensein des Keys zu prüfen?
Oder utnerscheidet sich das vom reinen Ablauf her nicht und jeder hat seinen eigenen Stil?


Gruß
Sparrow
lunar

@sparrow: Ist bei Wörterbücher mehr eine Frage des persönlichen Stils und Geschmacks. Bei externen Resourcen (e.g. Dateien) ist eine vorherige Prüfung allerdings falsch, das nur als Anmerkung am Rande.

Bei Wörterbüchern kann man auch ".get()" verwenden, um entweder den Wert des Schlüssels oder einen Standardwert zurückgeben zu lassen, falls der Schlüssel nicht existiert:

Code: Alles auswählen

old_value = nr2value.get(article.nr)
if old_value is not None:
    article.oldValue = old_value
Diese Lösung finde ich persönlich schöner als das Abfangen einer Ausnahme mit leerem Block. Der Standardwert (in diesem Fall "None") darf dann nur kein möglicher Wert im Wörterbuch sein.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

sparrow hat geschrieben:Ist es vorzuziehen die Exception zu fangen und nicht zu bahandeln oder vorher auf das vorhanensein des Keys zu prüfen?
Die Exception wird ja behandelt. Sie wird abgefangen und eine entsprechende Aktion ausgelöst, welche in diesem Fall darin besteht, mit der nächsten Artikel-Nummer weiter zu machen.

Exception-Handling in Python ist oft billiger als ein Funktionsaufruf. Deswegen verwendet man gerne das von BlackJack gezeigte Idiom. Das fällt unter das Prinzip: Easier to Ask Forgiveness than Permission (EAFP), im Gegensatz zu: Look Before You Leap (LBYL).

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
Antworten