Seite 1 von 1

Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 10:24
von mutetella
Hallo,

ich habe folgende Suchfunktion, die eine Sequenz, innerhalb der gesucht werden soll und je eine Liste mit Suchtermen die NICHT, UND oder ODER vorkommen sollen erwartet:

Code: Alles auswählen

def match(search_in, not_, and_, or_):
    def all_(iter_):
        for element in iter_:
            if not element:
                return False
        return bool(iter_)

    return any(map(lambda term: term in search_in, or_)) or \
        all_(map(lambda term: term not in search_in, not_) +
        map(lambda term: term in search_in, and_))
Dazu hätte ich zwei Fragen, die ich mir trotz längerem Doc-Lesen und stackoverflow-Stöbern nicht beantworten kann:

1. Lässt sich meine Funktion mit dem operator-Modul wesentlich vereinfachen?
Ich denke da an die Suchbegriffe der 'not_'- und 'and_'-Liste: Der Unterschied besteht 'ja nur' darin, dass ein Vergleich 'not in search_in' und 'in search_in' stattfindet. Könnte man das nicht 'in einem Aufwasch' erledigen anstatt die beiden 'map'-Ergebnisse zu verketten?

2. Wie ließe sich auf die 'all_'-Funktion verzichten?

mutetella

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 10:58
von snafu
Vielleicht erklärst du zunächst mal, was das Ziel dieser Funktion sein soll.

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 11:13
von mutetella
Nun ja, die Funktion 'match' gibt 'True' zurück, wenn die Elemente aus 'not_' nicht, die Elemente aus 'and_' schon oder eines der Elemente aus 'or_' in 'search_in' enthalten ist.
Die Funktion 'all_' macht dasselbe wie die built-in Funktion 'all', mit dem Unterschied, dass die Übergabe einer leeren Liste 'False' zurückgibt.

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 11:53
von snafu
Dann könnte man allein schon dein `all_()` abkürzen mit:

Code: Alles auswählen

def all_(iterable):
    return all(iterable) if iterable else False
Aber was ist denn nun das höhergeordnete Ziel der Funktion? Ich wollte eigentlich nicht wissen, was sie ausspuckt, sondern eher zu was sie gut ist.

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 12:01
von BlackJack
@mutetella: Ich finde den Ausdruck nach dem ``return`` ein wenig ungünstig formatiert. Vielleicht liegt es an meiner Unfähigkeit in umfangreicheren Ausdrücken die Klammern zu zählen, aber ich habe die letzten beiden Zeilen zuerst falsch gelesen als ``all_(map(…)) + map(…)``.

Vielleicht wäre es insgesamt übersichtlicher wenn Du das als `set`-Operationen formulierst!?

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 14:23
von mutetella
@snafu:
Danke, da hab' ich den kurzen Weg wieder mal nicht gesehen...
Die Funktion wird dafür verwendet, Termine/Notizen zu filtern, die z. B. der category 'Privat' UND 'Arbeit' oder 'Kids' UND NICHT 'Schule' etc. angehören.
Eine darüberliegende Klasse entwirft mir je nachdem, was gewünscht ist, die jeweiligen searchpatterns in Form von dictionaries:

Code: Alles auswählen

{'category': {'and_': ('Privat', 'Arbeit')}, {'not_': ('Schule')}ii}
@BlackJack:
Danke für den Tipp, Du hast Recht, lesbarer ist es allemal:

Code: Alles auswählen

def match(search_in, not_, and_, or_):
    search_in = set(search_in.split())
    return set(and_).issubset(search_in) and \
        set(not_).isdisjoint(search_in) or \
        bool(set(or_).intersection(search_in))
Nur: Wenn ich die Funktion auch zur Volltextsuche verwenden möchte, klappt das nicht mehr, da ein 'arzt' in 'Zahnarzt' nicht gefunden wird.
Oder habe ich die 'set'-Funktionen falsch angewendet?

mutetella

Re: Könnte man hier das operator-Modul einsetzen?

Verfasst: Donnerstag 7. Juli 2011, 15:37
von BlackJack
@mutetella: Wenn auch Teilwörter treffen sollen, dann geht es nicht mit `set`\s. Ich dachte `search_in` wäre auch eine Liste von Begriffen.