Seite 1 von 1

Suchlauf für nix

Verfasst: Dienstag 8. September 2015, 20:20
von DMD
hi
hab den code von snafu (danke nochmal) jetzt für mich umgeändert,
und weiterprobiert und bin schon wieder an der grenze des möglichen:)

Code: Alles auswählen

import calendar

def monatTreffer(pfadNamen):
    monat_names = calendar.month_name[1:]
    for position, s in enumerate(pfadNamen):
        for monat_name in monat_names:
            if monat_name in s:
                yield position, monat_name

#pfadNamen = [u'C:', u'Users', u'DMD-OL', u'Desktop', u'Arbeitszeitverwaltung', u'Kalenderuebersichten', u'2020', u'January 2020', u'Daniel Olling_16.01.2020.pdf']
pfadNamen =[u'C:', u'Users', u'DMD-OL', u'Desktop', u'Arbeitszeitverwaltung', u'Kalenderuebersichten', u'2020', u'Neuer Ordner', u'Christian Olling_08.01.2020.pdf']

for position, monat_name in monatTreffer(pfadNamen):
    if position == 7:
        print position
    else:
        print 'Not there'
wenn im pfadNamen kein monatsname vorhanden ist, soll er mir das mit 'Not there' sagen.
funktioniert leider nicht. hilfe?
ach und...mit position = [] und position.append funktioniert es auch nicht.

Re: Suchlauf für nix

Verfasst: Dienstag 8. September 2015, 23:12
von snafu
Wenn kein Monat gefunden wird, dann spuckt die Funktion `monatTreffer()` auch kein Ergebnis aus. Hierdurch kommt es in deinem Code auf Modulebene, der ja auf `monatTreffer()` basiert, zu keinem einzigen Schleifendurchlauf. Somit wird der `else:`-Teil vom Programmfluss überhaupt nicht beachtet, da eben der innere Block deiner Schleife gar nicht erst betreten wird.

Du könntest via ``list(monatTreffer(pfadNamen))`` eine Liste erzeugen. Listen ohne Inhalt geben in Python immer den Wahrrheitswert `False` zurück. Insofern wäre das grobe Schema:

Code: Alles auswählen

treffer = list(monatTreffer(pfadNamen))
if not treffer:
    print 'Not there'

Re: Suchlauf für nix

Verfasst: Mittwoch 9. September 2015, 00:40
von cofi
Alternativ kannst du in `monatTreffer` eine Exception werfen oder z.B. None zurueckgeben wenn nichts gefunden wird.

Re: Suchlauf für nix

Verfasst: Mittwoch 9. September 2015, 09:57
von BlackJack
@cofi: Das würde ich nicht machen, denn das Verhalten kann man ganz einfach mit der `next()`-Funktion erreichen: Falls es keinen Treffer gibt löst ``next(monat_treffer(pfad_teile))`` eine Ausnahme (`StopIteration`) aus, auf die man reagieren kann, und ``next(monat_treffer(pfad_teile), None)`` gibt `None` zurück.

Re: Suchlauf für nix

Verfasst: Mittwoch 9. September 2015, 10:19
von snafu
cofi hat geschrieben:Alternativ kannst du in `monatTreffer` eine Exception werfen oder z.B. None zurueckgeben wenn nichts gefunden wird.
Das widerspricht IMHO dem gängigen Verhalten von Iteratoren. Da finde ich den Vorschlag von BlackJack deutlich flexibler.

Aber ehrlich gesagt würde ich bei einer überschaubaren Eingabemenge wohl trotzdem auf die `list`-Variante setzen, da mir diese lesbarer erscheint. Zumal man sich damit Verrenkungen erspart, falls mit den Elementen des Iterators, falls welche vorhanden sind, noch etwas gemacht werden soll. Dann müsste man nämlich das zuvor herausgezogene Element wieder zurücklegen bzw es sich irgendwie merken, damit es nicht verloren geht. Eine Lösung dafür wäre das behelfsmäßige Anlegen einer neuen Liste, wo alle aus dem Iterator abgefragten Elemente aufbewahrt werden. Und dann kann man ja gleich, wie von mir vorschlagen, den Iterator als Argument an `list()` übergeben.

Falls man es aber z.B. mit hunderten MB an Daten zu tun hat, dann würde ich eine rein iteratorbasierte Lösung bevorzugen, um den Speicherverbrauch bei der Verarbeitung in Grenzen zu halten. Und dafür ist der gezeigte Algorithmus ja dank `yield` auch ausgelegt.

Re: Suchlauf für nix

Verfasst: Mittwoch 9. September 2015, 12:45
von snafu
Und noch etwas: Es sieht ja nun so aus als ob der Funktion immer die einzelnen Segmente eines Pfades übergeben werden sollen. In diesem Fall ist ein `return` anstelle von `yield` wahrscheinlich sinnvoller, sofern feststeht, dass pro Pfad nur maximal ein Segment mit einem Moatsnamen enthalten sein kann. Wenn kein Monatsname enthalten ist, würde die Funktion automatisch `None` ausliefern. Da es sich dann auch um keinen Iterator mehr handelt, fände ich das `None` persönlich in Ordnung.

Wenn man will, dann kann man - wie schon vorgeschlagen wurde - aber auch eine Exception werfen, die aussagt, dass kein Monatsname enthalten war. Das ist sogar noch ein stückweit pythonischer. Die Funktion könnte dann so aussehen:

Code: Alles auswählen

import calendar

class NoMonthNameError(Exception):
    pass

def get_month_name_index(items):
    month_names = calendar.month_name[1:]
    for index, item in enumerate(items):
        for month_name in month_names:
            if month_name in item:
                return index
    msg = 'could not find a month name'
    raise NoMonthNameError(msg)

Re: Suchlauf für nix

Verfasst: Samstag 12. September 2015, 04:41
von DMD
danke, funzt
Ihr seid die besten :)