Seite 1 von 1

Inverser Filter in unter 42 Zeichen?

Verfasst: Mittwoch 21. Januar 2009, 10:54
von steps
Hallo zusammen!

Ich stehe vor einem vielleicht etwas ungewöhnlichen Problem und erhoffe mir hier etwas Hilfe, da ich allein nicht auf die Lösung komme.

Mein Problem ist das folgende: Ich möchte einen inversen Filter schreiben. Das soll eine Methode sein, die als Argumente einerseits eine Liste und andererseits eine weitere Methode akzeptiert. Der Filter soll dann diejenigen Elemente aus der Liste zurückgeben (wieder als Liste), für die die übergebene Funktion False geliefert hat.

Ein Beispiel:

Die übergebene Methode prüft für jedes Element, ob es eine gerade Zahl ist und liefert True, falls das der Fall ist, sonst False.
Der Filter gibt dann entsprechend eine Liste ungerader Zahlen zurück (wenn man eine Liste mit Zahlen übergibt, versteht sich).

An sich ist diese Aufgabe nicht sonderlich schwer. Allerdings ist eine der Anforderungen an den Filter, dass er in weniger als 42 Zeichen realisiert werden soll (ist eine Idee von einem Professor von mir).

Meine bisherige Lösung:

Code: Alles auswählen

def k(l,f):return filter(lambda x:not f(x),l)
Das sind 45 Zeichen, wenn ich mich nicht verzählt habe.

Beispiel für die Verwendung:

Code: Alles auswählen

liste=[1,2,3,4,5,6,7,8,9,0]

def k(l,f):return filter(lambda x:not f(x),l)

def testfunc(testee):
    return testee % 2 == 0

newlist=k(liste,testfunc)
print newlist
Für die Zahl der Zeichen gilt nur die Filter-Funktion selbst, der Rest ist nur zum Testen. Entsprechend sind Abkürzungen wie

Code: Alles auswählen

fi=filter
nicht drin, da sie den Code sogar noch verlängern würden.

Also, nochmal meine Frage ganz konkret:

Hat jemand eine Idee, wie man die Zeile

Code: Alles auswählen

def k(l,f):return filter(lambda x:not f(x),l)
auf weniger als 42 Zeichen reduziert, wobei sie natürlich weiterhin die bisherige Funktionalität behalten soll?

Notwendige Whitespaces zählen leider dazu...

Würde mich sehr über Anregungen bzw. Ideen freuen!


Greets und Danke schonmal - steps

P.S: Das ist keine Hausaufgabe oder so, sondern mehr ein Denkspiel (bin neu hier und habe gerade erst den Thread über Hausaufgaben etc. gelesen) und ich suche auch nicht nach einer vorgefertigten Lösung...hoffe, dass sich meine Anfrage im Rahmen befindet.

Verfasst: Mittwoch 21. Januar 2009, 11:04
von Käptn Haddock
Du könntest die Bedingung so formulieren, das das 'not' wegfällt. Fällt mir nur so ein, ich kenn mich damit noch net so aus ;)

CU UWe

Verfasst: Mittwoch 21. Januar 2009, 11:05
von tiax
Mit List Comprehension:

Code: Alles auswählen

def k(l,f):return [not f(i) for i in l]

Verfasst: Mittwoch 21. Januar 2009, 11:12
von Leonidas
Hallo steps, willkommen im Forum,

39 Zeichen:

Code: Alles auswählen

k=lambda l,f:[e for e in l if not f(e)]
Kannst ja ein paar Leerzeichen reinmachen, dann kommt man auch auf 42.

tiax, deine Funktion negiert die Argumente der Liste und ist eher mit ``map`` vergleichbar.

Verfasst: Mittwoch 21. Januar 2009, 11:16
von helduel
tiax hat geschrieben:Mit List Comprehension:

Code: Alles auswählen

def k(l,f):return [not f(i) for i in l]
Das gibt lediglich eine Liste mit True und False zurück.

40 Zeichen:

Code: Alles auswählen

k=lambda l,f:filter(lambda x:not f(x),l)
Gruß,
Manuel

Verfasst: Mittwoch 21. Januar 2009, 11:25
von steps
Wow, das ging ja mal schnell :D

Bin noch nicht sonderlich lang im Python-Lager (aber jetzt schon Fan) und habe doch glatt vergessen, dass lambda ja auch etwas zurückgibt! :idea:

So kriegt man das tatsächlich hin, danke euch :)

@Leonidas: Muss ich gar nicht auffüllen, soll ja unter 42 Zeichen sein, also ist kürzer sogar besser.

Da ich noch nicht so bewandert bin, hab ich da doch glatt mal noch eine Frage zu deiner Version, Leonidas.
Kann man das so interpretieren:

"Für jedes e in l, gib e zurück, wenn f(e) False ist?" oder liest sich das anders? Diese Notation "e for e..." ist mir immer noch etwas befremdlich.

Auf jeden Fall vielen Dank euch allen, Problem gelöst!

Greets - steps

Verfasst: Mittwoch 21. Januar 2009, 11:51
von Leonidas
steps hat geschrieben:"Für jedes e in l, gib e zurück, wenn f(e) False ist?" oder liest sich das anders?
Nein, das stimmt genau so.

Verfasst: Mittwoch 21. Januar 2009, 12:11
von audax

Code: Alles auswählen

f=compose(list,ifilterfalse)
*duck*

Verfasst: Mittwoch 21. Januar 2009, 12:12
von steps
audax hat geschrieben:

Code: Alles auswählen

f=compose(list,ifilterfalse)
*duck*
Ok, den versteh ich nun wirklich nicht...könntest du mir den bitte erklären? Sieht ja schon interessant aus :)

Greets - steps

Verfasst: Mittwoch 21. Januar 2009, 12:28
von audax
Ich nutz gerne ein Modul von mir, in dem Compose definiert ist als

Code: Alles auswählen

    def compose(f, g, doc=None):
        def composed(*args, **kwargs): return f(g(*args, **kwargs))
        composed.__doc__ = doc
        return composed
und ifilterfalse kommt aus dem itertools Modul :)

Fakeedit:
CGIWrap encountered a system error:

When: could not fork
Error Message: Resource temporarily unavailable
Error Number: 11
Ich will Inyoka :o

Verfasst: Mittwoch 21. Januar 2009, 12:44
von steps
Ach so, ok. Hatte mich schon gewundert :D

Danke auf jeden Fall!

Greets - steps