LC mit Bedingungen, gehts einfacher?

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
Gnushi
User
Beiträge: 77
Registriert: Dienstag 12. Dezember 2006, 09:49

Hallo zusammen!

Ich möchte gerne eine Liste durch Einschränkung einer anderen Liste erzeugen. Mein gegenwärtiger Code sieht etwa so aus:

Code: Alles auswählen

class A(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def vals(self):
        return (self.x, self.y)

liste1 = [A(1, 1), A(2, 2), A(7, 9)]

def f(s, a, b):
    v = s.vals()
    return v[0] == a and v[1] == b

liste2 = [s for s in liste1 if f(s, 7, 9)]
for o in liste2:
    print o.vals()
Hier wird eine Liste "liste2" aus der Liste "liste1" erzeugt, wobei zwei Bedingungen erfüllt sein müssen. Ich würde mir gerne die Definition der Funktion "f" ersparen, stattdessen einen lambda-Ausdruck und filter() verwenden oder was auch immer. Die Methode vals() soll aber auch nur einmal pro Element aufgerufen werden. Leider erlaubt Lambda keine Zuweisung. Hat jemand eine Idee für besseren Code?

Liebe Grüße

GnuShi
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

liste2 = filter(lambda s: s.vals() == (7,9), liste1)
Ein schönerer Ansatz wäre es aber wohl, die __eq__-Methode für die Klasse A zu definieren.
Gnushi
User
Beiträge: 77
Registriert: Dienstag 12. Dezember 2006, 09:49

Hi EyDu!
EyDu hat geschrieben:

Code: Alles auswählen

liste2 = filter(lambda s: s.vals() == (7,9), liste1)
Ein schönerer Ansatz wäre es aber wohl, die __eq__-Methode für die Klasse A zu definieren.
Vielen dank für die Antwort. Bei der Antwort ist mir dann aufgefallen, dass ich das Problem zu stark vereinfacht habe:

Hier nochmal, wobei ich in der Klasse drei Parameter habe, mich aber nur 2 davon interessieren. Die Klasse A hat in Wirklichkeit noch mehr Attribute, die ich bei __eq__() allesamt vergleichen müsste. Hinzu kommt, dass ich in verschiedenen Kontexten echte Teilmengen der Attribute vergleichen muss.

Code: Alles auswählen

class A(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def vals(self):
        return (self.x, self.y, self.z)

liste1 = [A(1, 1, 1), A(7, 9, 2), A(7, 9, 1)]

def f(s, a, b):
    v = s.vals()
    return v[0] == a and v[1] == b

liste2 = [s for s in liste1 if f(s, 7, 9)]
for o in liste2:
    print o.vals()
Liebe Grüße

GnuShi
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Gehe ich richtig in der Annahme, dass das folgende dann auch noch zu einfach ist?

Code: Alles auswählen

liste2 = filter(lambda s: s.vals()[:2] == (7,9), liste1)
Gnushi
User
Beiträge: 77
Registriert: Dienstag 12. Dezember 2006, 09:49

Hi!
EyDu hat geschrieben:Gehe ich richtig in der Annahme, dass das folgende dann auch noch zu einfach ist?
Nee genau richtig. Weiß nicht, warum ich da nicht selber drauf gekommen bin. Danke

Gruß

GnuShi
BlackJack

Und falls die Werte sich nicht so schön durch "slice"n aus dem Tupel holen lassen, gibt's `operator.itemgetter()`, dass seit Python 2.5 auch mehr als einen Index/Schlüssel entgegen nimmt.
Antworten