Station - Der filter-Operator
Beispiel: Datensätze herausfiltern
Die Liste der Datensätze zur Verwaltung der Mitglieder des Sportvereins soll nach verschiedenen Kriterien durchsucht werden: Wer gilt als erwachsen (d.h. ist am Ende des Jahres mindestens 18 Jahre alt)? Wer hat im Februar Geburtstag? Wer hat einen Nachnamen, der mit S beginnt? Es sollen alle Datensätze, die das jeweilige Suchkriterium erfüllen, ermittelt werden.
Eine erstes funktionales Programm
Ein erstes Programm benutzt die folgende Funktion, um die gesuchten Datensätze aus der Liste aller Datensätze herauszufiltern.
def erwachsenHerausfiltern(liste): if liste == []: return liste else: person = liste[0] geburtsdatum = person[2] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter >= 18: return [liste[0]] + erwachsenHerausfiltern(liste[1:]) else: return erwachsenHerausfiltern(liste[1:]) # Test personendaten = [ ('Jennifer', 'Abel', (15,12,1993)), ('Philipp', 'Bach', (21,4,1997)), ('Andreas', 'Beyer', (16,3,1988)), ('Alexander', 'Heinrich', (17,3,1999)), ('Tobias', 'Klein', (1,3,1997)), ('Britta', 'Koch', (23,5,1995)), ('Maximilian', 'Meyer', (21,6,1986)), ('Adriana', 'Müller', (21,1,2001)), ('Silke', 'Schmidt', (13,7,1990)), ('Oliver', 'Schmitt', (14,4,1994)), ('Simone', 'Schuster', (20,12,2000)), ('Pia', 'Schwarz', (11,11,2003)), ('Paul', 'Schwarz', (11,11,2003))] # Anfrage 1 print(erwachsenHerausfiltern(personendaten))
Aufgabe 1
(a) Entwickle entsprechende Funktionsdefinitionen, um die Datensätze zu den beiden anderen oben genannten Kriterien herauszufiltern.
(b) Beschreibe das Schema, das all diesen Filteroperationen zu Grunde liegt.
(c) Siehst du eine Möglichkeit, eine Funktion höherer Ordnung zu benutzen, um das gemeinsame Berechnungsschema zu erfassen?
Der filter-Operator
Funktionsdefinitionen zum Herausfiltern von Datensätzen, die ein bestimmtes Kriterium erfüllen,
können alle nach dem gleichen Schema aufgebaut werden. Wenn eine Liste liste = [e0, e1, e2, ...]
und eine Filterfunktion f: x -> True/False
, die eine Bedingung an die Listenelemente
beschreibt, gegeben sind, dann soll der filter-Operator die Teilliste
all der Elemente von liste
ermitteln, die die Bedingung erfüllen:
Den Bezeichner myFilter
wählen wir, da es filter
bereits als vordefinierten
Bezeichner in Python gibt.
Wenn man jetzt Funktionen wie erwachsen
und imFebruarGeboren
zur
Implementierung von Bedingungen definiert,
so kann man den filter-Operator wie folgt einsetzen.
Die Funktion myFilter
ist eine Funktion höherer Ordnung. Eine Implementierung (und Verwendung)
könnte so aussehen:
def myFilter(liste, f): if liste == []: return liste else: if f(liste[0]): return [liste[0]] + myFilter(liste[1:], f) else: return myFilter(liste[1:], f) # Test personendaten = [ ('Jennifer', 'Abel', (15,12,1993)), ('Philipp', 'Bach', (21,4,1997)), ('Andreas', 'Beyer', (16,3,1988)), ('Alexander', 'Heinrich', (17,3,1999)), ('Tobias', 'Klein', (1,3,1997)), ('Britta', 'Koch', (23,5,1995)), ('Maximilian', 'Meyer', (21,6,1986)), ('Adriana', 'Müller', (21,1,2001)), ('Silke', 'Schmidt', (13,7,1990)), ('Oliver', 'Schmitt', (14,4,1994)), ('Simone', 'Schuster', (20,12,2000)), ('Pia', 'Schwarz', (11,11,2003)), ('Paul', 'Schwarz', (11,11,2003))] def erwachsen(person): geburtsdatum = person[2] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter >= 18: return True else: return False def imFebruarGeboren(person): geburtsdatum = person[2] monat = geburtsdatum[1] if monat == 2: return True else: return False def nameBeginntMitS(person): name = person[1] if name[0] == 'S': return True else: return False # Anfrage 1 print(myFilter(personendaten, erwachsen)) # Anfrage 2 print(myFilter(personendaten, imFebruarGeboren)) # Anfrage 3 print(myFilter(personendaten, nameBeginntMitS))
Welche Vorteile bietet der filter-Operator? Er liefert eine Standardlösung für eine sehr allgemeine Problemklasse. Wenn man diese Standardlösung benutzt, muss man das Rad nicht jedesmal neu erfinden. Man kann verschiedene Teilprobleme entkoppeln, verringert Fehlerquellen, vermeidet u.U. Codeduplizierung, ...
Noch eine Python-Implementierung des filter-Operator
In Python kann die Funktion myFilter
auch ganz kurz so implementiert werden:
def myFilter(liste, f): return [x for x in liste if f(x)]
Diese Implementierung nutzt eine sogenanne List-Comprehension. Das ist eine Anweisung, mit der man in Python eine Liste elegant erzeugen kann.