Suchlauf für nix

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
DMD
User
Beiträge: 123
Registriert: Sonntag 17. Mai 2015, 03:34

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.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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'
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Alternativ kannst du in `monatTreffer` eine Exception werfen oder z.B. None zurueckgeben wenn nichts gefunden wird.
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.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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)
DMD
User
Beiträge: 123
Registriert: Sonntag 17. Mai 2015, 03:34

danke, funzt
Ihr seid die besten :)
Antworten