Seite 1 von 1

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

Verfasst: Samstag 1. Mai 2010, 17:03
von ayJay
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?

Verfasst: Samstag 1. Mai 2010, 17:09
von DasIch

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

Verfasst: Samstag 1. Mai 2010, 17:10
von 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)

Verfasst: Samstag 1. Mai 2010, 17:20
von ayJay
Das war fix, großes Dankeschön an euch beide. __eq__() brauche ich (wahrscheinlich) noch anderweitig, aber any() war genau das, was ich suchte!

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

Verfasst: Samstag 1. Mai 2010, 18:11
von Darii
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)

Verfasst: Samstag 1. Mai 2010, 18:38
von ayJay
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...

Verfasst: Samstag 1. Mai 2010, 18:41
von DasIch
@ayJay Dieser Ausdruck ist eine generator expression und die wird Schritt für Schritt durchlaufen bis any() dass erste mal auf True stößt.

Verfasst: Samstag 1. Mai 2010, 19:05
von Darii
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