"in"-Operator, aber auf Attribute...

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
ayJay
User
Beiträge: 17
Registriert: Dienstag 20. Mai 2008, 01:10

Hallo, ich weiß leider überhaupt nicht, wonach ich suchen soll, deswegen muss ich direkt fragen:

Ich habe eine Liste von Objekten, die z.B. ein Attribut name haben. Nun möchte ich herausfinden, ob ein Objekt mit einem bestimmten Namen in der Liste enthalten ist. Ungefähr so:

Code: Alles auswählen

class Test:
  def __init__(self, name):
    self.name = name

liste = [Test("eins"), Test("zwei"), Test("drei")]
Was jetzt natürlich nicht geht, ist

Code: Alles auswählen

if "eins" in liste.name
Was ich nicht schön finde, ist

Code: Alles auswählen

if "eins" in [t.name for t in liste]
Nicht schön, weil: [halbwissen]Die list comprehension läuft erst komplett durch, auch wenn schon beim ersten Objekt der Treffer gefunden würde[/halbwissen]

Fragen: ist das so? Und wenn ja: wie geht es schöner?
Wars don't determine who's right - only who's left
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

>>> class Test(object):
...     def __init__(self, name):
...         self.name = name
... 
>>> liste = [Test("eins"), Test("zwei"), Test("drei")]
>>> any(t.name == "eins" for t in liste)
True
lunar

Falls Du nur mit "name" vergleichen musst, kannst Du in Test den Gleichheitsoperator überladen (__eq__()), so dass Exemplare der Klasse mit Zeichenketten verglichen werden können. Dann funktioniert der "in"-Operator:

Code: Alles auswählen

'eins' in liste
Alternativ kannst Du any() nutzen:

Code: Alles auswählen

any(t.name == 'eins' for t in liste)
ayJay
User
Beiträge: 17
Registriert: Dienstag 20. Mai 2008, 01:10

Das war fix, großes Dankeschön an euch beide. __eq__() brauche ich (wahrscheinlich) noch anderweitig, aber any() war genau das, was ich suchte!
Wars don't determine who's right - only who's left
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

ayJay hat geschrieben:Fragen: ist das so? Und wenn ja: wie geht es schöner?
Indem du eine generator expression verwendest.

Code: Alles auswählen

if "eins" in (t.name for t in liste)
ayJay
User
Beiträge: 17
Registriert: Dienstag 20. Mai 2008, 01:10

Ist das nicht genau das, was ich in meinem Beitrag schon stehen hatte? Bei dir ist es in Tupel, hat das Relevanz?

Und bei any fällt mir auch grad auf, dass das ja nur eine "andere Schreibweise" ist, wird da nicht auch erst der innere Ausdruck

Code: Alles auswählen

t.name == "eins" for t in liste
zu [True, False, False, ...] ausgewertet und darauf any() angewendet? Grade diese komplette Erstellung der Liste möchte ich gerne vermeiden...
Wars don't determine who's right - only who's left
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@ayJay Dieser Ausdruck ist eine generator expression und die wird Schritt für Schritt durchlaufen bis any() dass erste mal auf True stößt.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

ayJay hat geschrieben:Ist das nicht genau das, was ich in meinem Beitrag schon stehen hatte? Bei dir ist es in Tupel, hat das Relevanz?
Nein, deswegen habe ich das ja auch generator expression genannt. Da hättest du auch ruhig selbst nach googeln können: http://docs.python.org/tutorial/classes ... xpressions
Antworten