Inverser Filter in unter 42 Zeichen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
steps
User
Beiträge: 4
Registriert: Mittwoch 21. Januar 2009, 10:36

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.
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

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
---------------------------------
have a lot of fun!
Benutzeravatar
tiax
User
Beiträge: 152
Registriert: Samstag 23. Juli 2005, 17:28
Kontaktdaten:

Mit List Comprehension:

Code: Alles auswählen

def k(l,f):return [not f(i) for i in l]
Ne invoces expellere non possis
[url=xmpp://florian@florianheinle.de]xmpp:florian@florianheinle.de[/url]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
Zuletzt geändert von Leonidas am Mittwoch 21. Januar 2009, 11:17, insgesamt 1-mal geändert.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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
Benutzeravatar
steps
User
Beiträge: 4
Registriert: Mittwoch 21. Januar 2009, 10:36

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

f=compose(list,ifilterfalse)
*duck*
Benutzeravatar
steps
User
Beiträge: 4
Registriert: Mittwoch 21. Januar 2009, 10:36

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
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

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
Benutzeravatar
steps
User
Beiträge: 4
Registriert: Mittwoch 21. Januar 2009, 10:36

Ach so, ok. Hatte mich schon gewundert :D

Danke auf jeden Fall!

Greets - steps
Antworten