Objekt Array, Duplikate löschen

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
Bioaim
User
Beiträge: 4
Registriert: Donnerstag 24. März 2016, 14:19

Hallo Leute,

ich habe ein Array, die Event Objekte enthalten. Ein Event besitzt eine TypeId (immer gleich), einen Namen und ein Datum.

In dem Array sind Duplikate vorhanden, die ich jetzt los werden will. Ich hab das ganze versucht in ein Set umzuwandeln, leider bleibe dabei aber die Duplikate vorhanden. (weil natürlich nicht der Inhalt des Arrays auf Gleichheit geprüft wird).

Mein Ansatz war dieser: (Pseudocode)

Code: Alles auswählen

for e, index in enumerate(events):
	for l, index2 in enumerate(events, start=index+1):
		if events[index].name == events[index2].name and events[index]date == events[index2].date 
Leider bekomm ich beim Durchsuchen des letzten Items vom Array einen IndexNotInRange Error, da ich ja den zweiten Index auf Index+1 setzte...

Was wäre also die richtige Art das ganze zu realisieren?

Danke für eure Antworten.

LG
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Bioaim: der "Pseudocode" funktioniert schon allein deshalb nicht, weil Du bei enumerate Index und Element vertauscht hast. Zum anderen macht es nicht das, was Du willst.
Wenn Du wirklich nur TypeId Name und Datum hast, sollte ein Set funktionieren. Du mußt halt die Gleichheitsmethode __eq__ und __hash__ der Event-Objekte implementieren. Alternativ hilft hier ein Wörterbuch:

Code: Alles auswählen

unique_events = {}
for event in events:
    unique_events[event.name, event.date] = event
BlackJack

@Bioaim: Array? Eventuell nicht doch eine Liste?

Das könnte man mit einem Wörterbuch lösen das Tupel von Name und Datum auf das Ereignisobjekt abbildet. Wenn Du so alle Objekte eingetragen hast, kannst Du die Werte von dem Wörterbuch abfragen und hast keine Duplikate mehr. Falls die Reihenfolge wichtig ist, dann hilft `collections.OrderedDict` eventuell. Falls das nicht die gewünschte Reihenfolge liefert, dann könnte man sich mit einem `set()` merken welche (Name, Datum)-Paare man schon gesehen hat und entsprechend das Element zum Ergebnis hinzufügen oder nicht.
Bioaim
User
Beiträge: 4
Registriert: Donnerstag 24. März 2016, 14:19

Hab vergessen zu erwähnen, dass ein Event noch weitere Attribute besitzt: LocationId, Subtitle, Genre, die aber alle nicht verwendent werden sollen, um Events auf Gleichheit zu prüfen.

Wie würden denn meine EQ und HASH Methoden aussehen, wenn ich prüfen will, ob Name und Datum gleich sind?

Bin normalerweise nicht mit Python unterwegs, sorry.
Bioaim
User
Beiträge: 4
Registriert: Donnerstag 24. März 2016, 14:19

Okay, hab das nun mit einem Wörterbuch probiert. Das ganze funktioniert, beinhaltet also keine Duplikate mehr. Das Problem dabei ist, dass ich jetzt nur noch den Namen und und das Datum habe, wie kann ich wieder auf alle Attribute zugreiffen?

Code: Alles auswählen

unique_events = {}
for event in events:
    unique_events[event.name, event.start_date] = event
    
return unique_events
BlackJack

@Bioaim: Wieso hast Du nur noch die Tupel? Auf was hast Du die denn abgebildet? Oder weisst Du jetzt nur nicht wie Du an die Werte kommst? Da gibt es verschiedene Methoden für auf `dict`. Je nach dem wie man die gerne hätte (Liste, Iterator).
Bioaim
User
Beiträge: 4
Registriert: Donnerstag 24. März 2016, 14:19

Hab mich falsch ausgedrückt, wusste nur nicht, wie ich jetzt wieder an die Daten komme, habs aber geschafft :)

Code: Alles auswählen

for key, value in events:
	print events[key, value].name
Danke euch!
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Es wäre ganz einfach:

Code: Alles auswählen

for event in events.values():
    print(event.name)
Oder ohne explizite Schleife:

Code: Alles auswählen

from operator import attrgetter

map(attrgetter('name'), events.values())
Antworten