i

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:

Black-Box

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.

Black-Box

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.

Suche

v
10.1.3.3
www.inf-schule.de/deklarativ/funktionaleprogrammierung/datenobjekte/station_filter

Rückmeldung geben