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.