Python: Ist Element in Liste?

Gast #6246977
Lesenswert?

Moin,

in Python kann man sehr einfach überprüfen ob ein gesuchtes Element sich 
in einer Liste befindet:
1
liste = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
2
if "Di" in liste:
3
    tuwas()

Das klappt soweit ich weiß aber nur mit "primitiven Datentypen" (falls 
die in Python auch so genannt werden).
Ich habe aber eine Liste die keine primitiven Typen beinhaltet sondern 
Klassen mit Attributen.
1
class Wochentag:
2
    name = "Mo"

Die C-like Lösung wäre, händisch über die Liste zu iterieren und bei 
Erfolg ein Flag zu setzen:
1
istInListe = False
2
for elem in liste:
3
    if elem.name = "Di":
4
        istInListe = True
5
        break
6

7
if istInListe:
8
    tuwas()

Ich bin mir aber sicher dass Python für sowas syntaktischen Zucker 
mitbringt.
Ich weiß nur grad nicht unter welchen Begriffen ich suchen soll.

Versteht ihr mein Anliegen?
Hat jemand eine schöne Lösung?
Gast #6246997
Lesenswert?

wangnick schrieb:
> Ich meine das geht wenn die Klasse Gleichheit definiert (eq).

Das schränkt aber ein, wenn andere Eigenschaften geprüft werden sollen.

Ich würde die naheliegende Lösung (Schleife) pythonisch als list 
comprehension formulieren

if "Di" in [x.name for x in liste]:

Allerdings kriegt man so kein handle auf das Element, nützt also nur, 
wenn man wirklich nur wissen will, ob das Element in der Liste vorkommt.

Ob das reicht weiß nur der TO.
Gast #6247007
Lesenswert?

Statt in eine Liste musst du deine Instanzen in einen Klasse packen und 
in der Klasse die Magic Methods _contains_ definieren.

class WochentagListe():
   ...
   def add(self,obj)
      self.list.add(obj)
   def  __contains__(self,val):
      for elem in self.liste:
         if elem.name = val:
            return True
      return False #bin mir nicht sicher ob das genau so geht

WochentagListe1 = WochentagListe()

if "Di" in WochentagListe1:
    tuwas()

https://stackoverflow.com/questions/1964934/what-does-contains-do-what-can-call-contains-function
Gast #6247264
Lesenswert?

Dann hat er Code, der umständlicher ist, und trotzdem die klassische von 
ihm erwähnte for Schleife hat.

Wenn es schnell auf Kosten von leserlich sein soll, dann eher noch ein 
map()

if any(map(lambda x: x.name=="Di",list)):

Wenn nicht zeitkritisch, bin ich immer noch für die List comprehension. 
Recht schnell, und gut verständlich.

P. S. :
Karl schrieb:
> for elem in self.liste:
>          if elem.name = val:

Der Vergleichsoperator ist ==
Gast #6247359
Lesenswert?

Minimalist schrieb:
> Dann hat er Code, der umständlicher ist, und trotzdem die klassische von
> ihm erwähnte for Schleife hat.

Kommt darauf an wie und wo man es braucht. Bei einem
1
import Wochenliste
2

3
...
4

5
if ... in Wochenliste:
6
   pass

ist das sicher übersichtlicher, als die Schleife.

Minimalist schrieb:
> Der Vergleichsoperator ist ==
Hast du fein gemacht.

MaWin schrieb:
> Mit Generator statt list comprehension ist es schneller

Ja aber mit der Klassenvariante geht es noch schneller:
1
import time
2
import string
3
import random
4

5
class Wochentag():
6
    def __init__(self,str):
7
        self.name = str
8
class Wochenliste():
9
    def __init__(self):
10
        self.liste=[]
11
    def Add(self,Tag):
12
        self.liste.append(Tag)
13
    def  __contains__(self,val):
14
        for elem in self.liste:
15
            if elem.name == val:
16
                return True
17
        return False
18

19
liste=[]
20
Wochenliste1 = Wochenliste()
21
source = string.ascii_letters + "1234567890"
22
for j in range(10000000):
23
    randstr = ""
24
    for i in range(3):
25
        randstr += random.choice(source)
26
    Tag = Wochentag(randstr)
27
    liste.append(Tag)
28
    Wochenliste1.Add(Tag)
29

30
start = time.time()
31
if "abc" in (x.name for x in liste):
32
    pass
33
mid1 = time.time()
34
if "abc" in [x.name for x in liste]:
35
    pass
36
mid2 = time.time()
37
if "abc" in Wochenliste1:
38
    pass
39
end = time.time()
40

41
print('{:6.4f}s'.format(mid1-start), end='  ')
42
print('{:6.4f}s'.format(mid2-mid1), end='  ')
43
print('{:6.4f}s'.format(end-mid2), end='  ')

Ausgabe: 0.0142s  0.7429s  0.0069s


Denkt mal drüber nach!
Gast #6247566
Lesenswert?

Karl schrieb:
> Denkt mal drüber nach!

Ja gerne.

Generator vs. List comprehension: Laufzeitfaktor 1,9%
Klasse vs. List comprehension: Laufzeitfaktor 0,9%

Die Klasse ist deutlich aufwändiger und komplizierter zu verstehen.
Der Generator ist vom Aufwand praktisch kostenlos. Man muss nur zwei 
Klammern austauschen.
Jetzt muss man halt abwägen, ob dieser zusätzliche Vorteil es einem wert 
ist.
#6247617
Lesenswert?

Fragliches Benchmark. Ich glaube nicht, dass das für Listen mit 
irgendeiner relevanten Anzahl an Elementen Bestand hat. Hast du das 
ausprobiert?

Wie lange es dauert, eine Liste mit 5 Elementen zu durchsuchen, 
interessiert eh keinen. Wenn sich diese Frage stellt, ist Python völlig 
die falsche Sprache.
Gast #6247746
Lesenswert?

Moin, danke für die Rückmeldungen.
Ich muss das alles erst mal sacken lassen :-)

Die list-comprehension-Syntax gefällt mir.
Die kannte ich auch schon, leider mach ich nicht oft was mit Python 
weswegen ich solche Features immer wieder vergesse.

Leider habe ich nicht dran gedacht dass ich nach erfolgreicher Suche 
eine Referenz auf das Objekt brauche. Das kann die list-comprehension 
wohl nicht.
Also läufts wohl doch auf die c-Style-Schleife mit flag hinaus.
Wenn das gesuchte Objekt bereits in der Liste ist wird es zurückgegeben.
Wenn nicht wird es mittels append hinzugefügt und dann zurückgegeben.

Schön versteckt in einer Datenbank-Klasse.
Der User braucht sich also beim Zugriff nie drum kümmern ob es das 
Element bereits gibt, läuft alles im Hintergrund.
Gast #6247772
Lesenswert?

Karlo schrieb:
> Leider habe ich nicht dran gedacht dass ich nach erfolgreicher Suche
> eine Referenz auf das Objekt brauche. Das kann die list-comprehension
> wohl nicht.

Doch, natürlich.
Hier eine Möglichkeit:

>>> liste = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
>>> selection = [x for x in liste if x == "Di"]
>>> if selection:
...     print(selection[0])
...
Di


Das geht natürlich auch mit anderen Objekten. If-Abfrage dann 
entsprechend anpassen, wie in den Beispielen vorher.
Gast #6247778
Lesenswert?

Ich habs mir fast gedacht, das das Objekt noch gebraucht wird.
Dann macht es schon Sinn, die  _eq_  Methode anzulegen, und wie oben 
erklärt vorzugehen. Ggf die vorhandene Klasse erweitern.
Da du ja scheinbar eine Liste ohne Duplikate haben möchtest, würde ich 
die Objekte dann aber in einem "set" speichern, und mit .add() 
hinzufügen. Dann kümmert sich python darum, es nur hinzuzufügen, wenn es 
noch nicht drin ist. Schau dir den Datentyp Set einfach mal an.
Gast #6247832
Lesenswert?

MaWin schrieb:
> Generator vs. List comprehension: Laufzeitfaktor 1,9%
> Klasse vs. List comprehension: Laufzeitfaktor 0,9%

Prozentrechnung ist nicht deine Stärke.

MaWin schrieb:
> Die Klasse ist deutlich aufwändiger und komplizierter zu verstehen.

Nur wenn man nicht OO denkt.

Sven B. schrieb:
> Fragliches Benchmark. Ich glaube nicht, dass das für Listen mit
> irgendeiner relevanten Anzahl an Elementen Bestand hat. Hast du das
> ausprobiert?

Ich habe nicht damit angefangen über Schnelligkeit zu faseln. Das war 
MaWin.
Zur Frage: Je kürzer die Liste, je gleicher die Laufzeit.

Wenn es um Leserlichkeit und Wiederverwendbarkeit geht sind die Magic 
Methods klar im Vorteil. Und das war die Ausgangsfrage.
Gast #6247854
Lesenswert?

Karl schrieb:
> MaWin schrieb:
>> Generator vs. List comprehension: Laufzeitfaktor 1,9%
>> Klasse vs. List comprehension: Laufzeitfaktor 0,9%
>
> Prozentrechnung ist nicht deine Stärke.

Ja dann. Was ist denn das richtige Ergebnis?

>>> 0.0142/0.7429*100
1.911428186835375
>>> 0.0069/0.7429*100
0.9287925696594427
Gast #6247877
Lesenswert?

MaWin schrieb:
> Ja dann. Was ist denn das richtige Ergebnis?
>
>>>> 0.0142/0.7429*100
> 1.911428186835375

Also braucht man nur 1,9 % der ursprünglichen Laufzeit könnte sich also 
bei großen Sachen schon lohnen.

MaWin schrieb:
> Nein sind sie nicht. Der generator ist trivial zu lesen. Es ist eine
> Zeile, die man praktisch wie einen Satz lesen kann.

Nein

if ... in ...
ist deutlich besser zu lesen, als dein verschachteltes gefrickel.
Gast #6247895
Lesenswert?

Karl schrieb:
> if ... in ...
> ist deutlich besser zu lesen, als dein verschachteltes gefrickel.

Danke für die Bestätigung, dass der Generatorausdruck besser lesbar ist, 
als eine Klasse, die _contains_ implementiert. Hier nochmal der 
Generator:

> if "abc" in (x.name for x in liste):
Gast #6247899
Lesenswert?

Michi schrieb:
> Karl schrieb:
>>> Generator vs. List comprehension: Laufzeitfaktor 1,9%
>>> Klasse vs. List comprehension: Laufzeitfaktor 0,9%
>>
>> Prozentrechnung ist nicht deine Stärke.
>
> Die Version mit der Klasse ist also doppelt so schnell!

Korrekt. Die Klasse ist doppelt so schnell, wie der Generator. Und der 
Generator hat nur zwei Prozent der Laufzeit der List comprehension.

Merkste selbst?
Nein?

Der Schritt von Comprehension -> Generator ist trivial (Klammern 
austauschen) und bringt bereits 98% des Geschwindigkeitsvorteils.
Die komplizierte Klassenlösung bringt einen weiteren Prozentpunkt.
Gast #6247915
Lesenswert?

MaWin schrieb:
> Karl schrieb:
>> if ... in ...
>> ist deutlich besser zu lesen, als dein verschachteltes gefrickel.
>
> Danke für die Bestätigung, dass der Generatorausdruck besser lesbar ist,
> als eine Klasse, die contains implementiert. Hier nochmal der
> Generator:
>
>> if "abc" in (x.name for x in liste):

Oh da habe ich wohl zuweit abstrahiert.

if Objekt in ListOfObject:

vs

if Gefrickel in (x.name for x in listeOfGefrickel):

Ist es jetzt klarer?
Gast #6247935
Lesenswert?

MaWin schrieb:
> Nein. Du blendest weiterhin das zu implementierende und zu verstehende
> __contains__-Protokoll aus.

1. ist die __contains__-Method für jeden Depp zu verstehen, im Gegensatz 
zu deinem Generator
2. Spätestens wenn man es mehrmals braucht, spart es Zeichen.
3. Ist meine Lösung Python-Style und deine C-Style.
4. Es wurde nach einer Phyton-Style-Lösung gefragt.
Gast #6247951
Lesenswert?

Karl schrieb:
> Soll das ein Argument sein?

Ja.

> Weil Eine Glühbirne nur 2 % der Energie eines Feuers braucht, kann man
> auf LEDs verzichten!

Warum sollte eine Glühbirne nur 2% der Energie eines Feuers brauchen?
Die Glühbirne verbraucht ziemlich sicher mehr Energie, für die gleiche 
Helligkeit, wie ein Feuer. Vor allem wegen der Umwandlungsverluste von 
der Primärenergiequelle zum Licht.
Gast #6248074
Lesenswert?

MaWin schrieb:
> Trotzdem ist Python streng typisiert und jedes Objekt hat einen
> eindeutigen Typ.

Aber ich habe bisher immer gedacht, dass das der Interpreter 
entscheidet, welchen Datentyp er dann nimmt. Bei einem Text würde ich 
einen String nehmen und bei einer 100 ein Integer, bei einer 0,443 vlt 
ein double-Datentyp. Also ich habe in Python bisher noch nie speziell 
einen Datentypen hergestellt wie z.B. in C:

int i; double k;

Und wenn das geht, wüsste ich garnicht, wie die genauen Befehle dazu 
heißen.
Gast #6248123
Lesenswert?

mh schrieb:
> Karl schrieb:
>> Und warum erwartest du das?
>
> Weil es im Namen steht.

Ja genau das ist auch mein Problem mit diesem Ansatz. Die Klasse 
implementiert einen klitzekleinen Teil des Protokolls einer list-Klasse. 
Wenn man das macht, sollte man das wenigstens im Namen deutlich machen, 
dass es eben keine Liste im herkömmlichen Sinne ist. Es sei denn, die 
Klasse implementiert wirklich das komplette list-Protokoll oder ist von 
list abgeleitet.
Gast #6248139
Lesenswert?

mh schrieb:
> Und nicht etwas, das nur auf den ersten Blick wie eine Liste aussieht.

Wenn du es brauchst, kannst du auch mit Vererbung deine Klasse aus der 
Originalklasse ableiten.

mh schrieb:
> Weil es im Namen steht.

if Objekt in MyDefListOfObject:

So besser? Du solltest halt schon wissen, was es für eine Liste ist und 
was in der Liste ist. Weil

if "Di" in [x.name for x in liste]:

funktioniert auch nur wenn x.name
type(x.name) == str

Irgendwo muss man halt mal denken.
Gast #6248142
Lesenswert?

MaWin schrieb:
> Es sei denn, die
> Klasse implementiert wirklich das komplette list-Protokoll oder ist von
> list abgeleitet.

Dass nur ein Teil implementiert wird ist weniger das Problem. Es ist das 
andere Verhalten der implementierten Teile. Immerhin ist es so 
"einfach", dass es einem direkt um die Ohren fliegt, sollte man etwas 
"falsch" machen.
Gast #6248161
Lesenswert?

Karl schrieb:
> Weil
>
> if "Di" in [x.name for x in liste]:
>
> funktioniert auch nur wenn x.name
> type(x.name) == str

Nö, falsch.
Die beteiligten Typen müssen nur das __eq__-Protokoll so implementieren, 
dass der exakte Typ keine Rolle spielt. Das ist best practice.
Gast #6248162
Lesenswert?

mh schrieb:
> dass es einem direkt um die Ohren fliegt, sollte man etwas
> "falsch" machen.

Was soll man sich da vorstellen? Wir reden Hier über ein paar 
Codeschnipsel, nicht über eine hoch professionelle Implementierung.
Kannst du mal Beispiele liefern, was einem um die Ohren fliegen soll? 
Belegen, dass es mit:
if "Di" in [x.name for x in liste]
einem nicht um die Ohren fliegen kann? Nach deiner Auffassung müsste 
dann x ein Float sein, dass es einem nicht um die Ohren fliegt, weil x 
ist ja eine Zahl?
Der normale Mensch denkt halt nach was x ist und genauso kann man drüber 
nachdenken, was MyDefListOfObject ist.
Gast #6248177
Lesenswert?

Karl schrieb:
> Wenn du es brauchst, kannst du auch mit Vererbung deine Klasse aus der
> Originalklasse ableiten.

Das macht es nicht besser. Mit der _contains_ Methode ist es einfach 
keine Liste mehr.

> mh schrieb:
>> Weil es im Namen steht.
>
> if Objekt in MyDefListOfObject:
>
> So besser?

Ernsthaft?

Karl schrieb:
> Du solltest halt schon wissen, was es für eine Liste ist und
> was in der Liste ist.

Dafür ist der Name da. Wenn wir eh immer wissen was der Typ und Wert 
ist, können wir alles a0, a1, a2, ... nennen.

Karl schrieb:
> if "Di" in [x.name for x in liste]:
>
> funktioniert auch nur wenn x.name
> type(x.name) == str
Nein! Bedingung ist, dass x.name existiert.

Karl schrieb:
> Irgendwo muss man halt mal denken.

Besser beim Namen auswählen etwas mehr denken, als beim Lesen der Namen.
Gast #6248186
Lesenswert?

MaWin schrieb:
>> funktioniert auch nur wenn x.name
>> type(x.name) == str
>
> Nö, falsch.
> Die beteiligten Typen müssen nur das __eq__-Protokoll so implementieren,
> dass der exakte Typ keine Rolle spielt. Das ist best practice.

funktioniert war hier im Sinne von "erfüllt seine angedachte Funktion" 
gemein, nicht im Sinne von "liefert keine Fehlermeldung".
Gast #6248192
Lesenswert?

mh schrieb:
> Nein! Bedingung ist, dass x.name existiert.
>

Und wo wird das bei euch sichergestellt? Oh dein Beispiel wird bestimmt 
explodieren.

> Karl schrieb:
>> Irgendwo muss man halt mal denken.
>
> Besser beim Namen auswählen etwas mehr denken, als beim Lesen der Namen.

mh schrieb:
>> if Objekt in MyDefListOfObject:
>>
>> So besser?
>
> Ernsthaft?

Ja!

Wie würdest du es machen?
Gast #6248218
Lesenswert?

Karl schrieb:
>>> funktioniert auch nur wenn x.name
>>> type(x.name) == str


MaWin schrieb:
> Warum sollte es das nicht tun, wenn name ein von mir definierter Typ
> ist, der vergleichbar mit str ist?

Du definierst doch gar keinen Typ selbst, weil das nicht übersichtlich 
ist. War das nicht vor 10 Posts deine Aussage? Oder du definierst 
eingene Klasse nicht wenn du nur so recht hast und du definierst eigene 
Klassen, wenn nur nur so recht hast. Du verdrehst absichtlich die 
Aussagen anderer, nur um recht zu haben. Bist du damit zufrieden 
(rhetorische Frage):

type(x.name) like str
Gast #6248240
Lesenswert?

Karl schrieb:
> Wie würdest du es machen?

Was genau?

-Einen alternativen Namen für dein ListOfObject auswählen? Kann ich 
nicht. Und das zeigt mir, dass es eine schlechte Idee ist, es so zu 
lösen.

-Das ursprüngliche Problem lösen? Dafür bräuchte man eine bessere 
Beschreibung des Problems. Vermutlich mit
1
for wochentag in filter(lambda x: x.name == 'Mo', wochentagListe):
2
    tuwas(wochentag)
oder ähnlich.
Gast #6248282
Lesenswert?

mh schrieb:
> for wochentag in filter(lambda x: x.name == 'Mo', wochentagListe):
>     tuwas(wochentag)

filter und map kann man so gut wie immer durch comprehension/generator 
ersetzen.
1
for wochentag in (for x in wochentagListe if x.name == 'Mo'):
2
    tuwas(wochentag)

In diesem speziellen Fall ist aber sicher die triviale Variante besser:
1
for x in wochentagListe:
2
    if x.name == 'Mo':
3
        tuwas(wochentag)
Gast #6248343
Lesenswert?

MaWin schrieb:
> In diesem speziellen Fall ist aber sicher die triviale Variante besser:
> for x in wochentagListe:
>     if x.name == 'Mo':
>         tuwas(wochentag)

Full Ack!
Einfach, verständlich, und sehr wahrscheinlich spielt Tempo hier eh 
keine Rolle. Wenn doch wird sich das dann rausstellen.
premature optimization is the root of all evil
Gast #6248376
Lesenswert?

mh schrieb:
> -Einen alternativen Namen für dein ListOfObject auswählen? Kann ich
> nicht. Und das zeigt mir, dass es eine schlechte Idee ist, es so zu
> lösen.

Du hält also eine objektorientierten Lösung für eine schlechte Idee, 
weil bei Python ein stdtype list definiert ist und du keinen 
Variablennamen findest, der nicht Liste enthält? Eigenwillige Logik.

mh schrieb:
> -Das ursprüngliche Problem lösen? Dafür bräuchte man eine bessere
> Beschreibung des Problems. Vermutlich mit
> for wochentag in filter(lambda
> x: x.name == 'Mo', wochentagListe):
>     tuwas(wochentag)
> oder ähnlich.

Das ursprüngliche Problem war bereits gelöst. Der TO hat nach
Python-Stylischen Lösung mit "syntaktischem Zucker" gesucht und du 
präsentierst eine dreifach verschachtelte Lösung mit einer 
Lambdafunktion. Respekt!
https://treyhunner.com/2018/09/stop-writing-lambda-expressions/
Gast #6248385
Lesenswert?

Karl schrieb:
> und du
> präsentierst eine dreifach verschachtelte Lösung mit einer
> Lambdafunktion.

Ich weiß nicht, was das überhaupt für ein Argument sein soll.
Das ist nicht mehr oder weniger verschachtelt, als deine 
__contains__-Methode. Die wird auch verschachtelt aufgerufen, vom 
in-Operator. Mit dem Nachteil, dass das eben nicht offensichtlich ist.
Beitrag #6248410 wurde von einem Moderator gelöscht.
Beitrag #6248417 wurde von einem Moderator gelöscht.
#6249026
Lesenswert?

Karl schrieb:
> Ja aber mit der Klassenvariante geht es noch schneller:
> [...]
> Denkt mal drüber nach!

Also ich habe jetzt mal sehr intensiv darüber nachgedacht. Dabei bin ich 
leider zu einigen Ergebnissen gekommen, die Dich vermutlich nicht 
erfreuen werden...

1. "Premature Optimization is the root of all evil." (Donald E. Knuth)

Das ist der erste Hauptsatz der Performanceoptimierung. Die Aussage ist: 
winzige Teilaspekte eines Programms zu optimieren, ist total bescheuert. 
Es kommt darauf an, das gesamte Programm mit den gesamten Realdaten zu 
betrachten. Erst dann kann man irgendeine seriöse und valide Aussage 
über dessen Performance treffen und dieselbe exakt an den Stellen 
optimieren, wo es hakt. Alles andere macht den Code höchstens 
komplizierter, und ob er auf einer Liste mit 5 Millionen Einträgen 
ähnlich performt wie auf einer mit 50 Einträgen, ist... fraglich, 
vorsichtig gesagt. (Die Aussage ist von 1973 und heute nicht weniger 
wahr oder wichtig...)


2. "Measure, don't guess." (Kirk Pepperdine)

Dieser zweite Hauptsatz der Performanceoptimierung sagt, daß es völlig 
sinnlos ist, irgendetwas optimieren zu wollen, daß man nicht unter 
realen Bedingungen gemessen hat. Am Ende sind nämlich Deine Annahmen 
falsch und Du investierst Deine Arbeit in einen Teil Deines Code, der 
0.001 Prozent seiner Laufzeit ausmacht, anstatt daß Du Dich auf jenen 
Teil Deines Code konzentrierst, der 90% Deiner Laufzeit kostet.


3. "Make it work, make it right, make it fast." (Kent Beck)

Dies ist ein eher grundsätzliches Prinzip abseits der 
Performanceoptimierung, aber es spielt im Zusammenhand mit den 
vorherigen Sätzen eine wichtige Rolle. Wir werden daran erinnert, daß 
Software erst einmal laufen muß, dann korrekt laufen (also das Richtige 
(tm) tun muß), bevor man sich daran geben kann, sie schnell zu machen... 
mithin: ihre Performance zu optimieren.


Nach diesen Grundsätzen sind da aber dann auch noch die Python-Dinge...

Also, zunächst folgt Python dem Grundsatz "batteries included". Das 
heißt, es gibt einen riesigen Haufen von Modulen. Wenn es etwa um 
Wochentage geht, bieten sich das Standardmodul "datetime" und die 
Erweiterung "dateutils" an. Mit "localization" und 
"internationalization" ("l10n" und "i18n") gibt es fertige Module für 
genau dieses: Wochentage mit Abkürzungen und solches neisse Zeugs. Wenn 
es nicht nur um dieses winzige Array (besser wäre ein Tupel, nebenbei) 
mit den Wochentagen geht, sondern größere Arrays iteriert werden müssen, 
gibt es für Python ein paar Erweiterungen, welche sowas wunderbar 
parallelisieren können, nämlich numpy, scipy und pandas.

Ach ja, lieber TO: IMHO gehört solch ein Datenarray, bei dem die Daten 
sich nicht wiederholen (können), nicht in eine list() und nichtmal in 
ein tuple(), sondern in ein set(). Ich kenne Deine Daten aber nicht, 
daher: YMMV. ;-)
#6249027
Lesenswert?

Anfänger schrieb:
> MaWin schrieb:
>> Trotzdem ist Python streng typisiert und jedes Objekt hat einen
>> eindeutigen Typ.
>
> Aber ich habe bisher immer gedacht, dass das der Interpreter
> entscheidet, welchen Datentyp er dann nimmt. Bei einem Text würde ich
> einen String nehmen und bei einer 100 ein Integer, bei einer 0,443 vlt
> ein double-Datentyp. Also ich habe in Python bisher noch nie speziell
> einen Datentypen hergestellt wie z.B. in C:
>
> int i; double k;
>
> Und wenn das geht, wüsste ich garnicht, wie die genauen Befehle dazu
> heißen.

Najaaaa... Python ist tatsächlich streng, aber dynamisch typisiert, weil 
der Typ an den Wert gebunden ist, anstatt an den Variablennamen. Du 
kannst ein und derselben Variablen daher unterschiedliche Werte zuweisen 
(das ist jetzt nicht überraschend), aber diese Werte können auch 
unterschiedliche Typen haben:
1
a = 5   # int
2
a = '5' # str

ist daher vollkommen zulässig. Ein Sonderfall ist "'5' * 5": in Python 
kommt dann '55555' heraus, statt -- wie zum Beispiel in PHP -- 25.
#6249029
Lesenswert?

MaWin schrieb:
> mh schrieb:
>> Karl schrieb:
>>> Und warum erwartest du das?
>> Weil es im Namen steht.
>
> Ja genau das ist auch mein Problem mit diesem Ansatz. Die Klasse
> implementiert einen klitzekleinen Teil des Protokolls einer list-Klasse.
> Wenn man das macht, sollte man das wenigstens im Namen deutlich machen,
> dass es eben keine Liste im herkömmlichen Sinne ist. Es sei denn, die
> Klasse implementiert wirklich das komplette list-Protokoll oder ist von
> list abgeleitet.

Bitte entschuldigt, aber Ihr seid viel zu sehr von Datentypen 
beherrscht. Eine Liste in Python ist eine Liste, also etwas, das die 
ganze List-API (List-Protokoll) kann.

Aber: es gibt viele andere Objekte, die einen Teil der List-API 
implementieren, ohne tatsächlich eine Liste zu sein. Um das zu 
realisieren, besitzt Python sogar eigene Subprotokolle, im Falle einer 
(iterierbaren) Liste zum Beispiel iterable. iterable kann aber auch von 
anderen Objekten implementiert werden, zum Beispiel von solchen, welche 
die Builtin-Datentypen tuple() oder set() implemtentieren.
#6250051
Lesenswert?

Karlo schrieb:
> in Python kann man sehr einfach überprüfen ob ein gesuchtes Element sich
> in einer Liste befindet:
>
>
1
> liste = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
2
> if "Di" in liste:
3
>     tuwas()
4
>
>
> Das klappt soweit ich weiß aber nur mit "primitiven Datentypen" (falls
> die in Python auch so genannt werden).
> Ich habe aber eine Liste die keine primitiven Typen beinhaltet sondern
> Klassen mit Attributen.
>
>
1
> class Wochentag:
2
>     name = "Mo"
3
>
>
> ...
>
> Ich bin mir aber sicher dass Python für sowas syntaktischen Zucker
> mitbringt.
> Ich weiß nur grad nicht unter welchen Begriffen ich suchen soll.
>
> Versteht ihr mein Anliegen?
> Hat jemand eine schöne Lösung?

wangnick schrieb:
> Ich meine das geht wenn die Klasse Gleichheit definiert (__eq__).

Ok, language reference 6.10.2, Membership test operations: "For 
container types such as list, tuple, set, frozenset, dict, or 
collections.deque, the expression x in y is equivalent to any(x is e or 
x == e for e in y)."

Also geht folgendes:
1
class Wochentag:
2
    def __init__ (self,name):
3
        self.name = name
4
    def __eq__ (self,other):
5
        return type(other)==type(self) and self.name==other.name
6

7
mo = Wochentag("Mo")
8
di = Wochentag("Di")
9
mi = Wochentag("Mi")
10

11
li = (mo,mo,di,1.0,"")
12
print(di in li)
13
print(mi in li)

Für das simple Beispiel der Wochentage wäre Enum tatsächlich besser 
geeignet. Da diese Singletons sind, werden sie bei x in y durch den 
is-operator gefunden.

LG, Sebastian

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren