Ein Dict mit mehrfach vorkommenden Keys?

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
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Hallo Leute,

ich habe mal wieder ein Problem.

Ich parse eine HTML-Seite und sammle die benötigten Daten in einem Dict mit zugehörigem Key.
Am Ende will ich daraus eine XML-Datei machen.
So weit so gut.

Jetzt habe ich aber ein Problem wenn ich eine auflistung speichern möchte die die gleiche Art von Inhalten beinhalten soll.
Ich mache mal ein Beispiel mit einem Fußballmatch weil ich es anhand dieses Beispieles am besten verdeutlichen kann:

Code: Alles auswählen

matchlist.update({'spielort': { 'stadt': 'München', 'stadion': 'Allianz Arena', 'liga': '1.Bundesliga'}})
matchlist.update({'heim_team' : {'verein': 'Bayern München', 'rang': '5', 'spieltag': '18'}})
So weit so gut...

Jetzt kommen die Spieler die ich auch in der Matchlist haben will. Da diese jedoch ein Dict ist kann ich als Key ja nicht einfach 'spieler' benutzen. Denn so würde ich nur einen, und zwar den letzten Spieler in der Liste haben da jeder update den vorherigen Spieler ersetzen würde.

Ich dachte ich hänge dann eine Liste in das dict an die 'value'-Stelle rein. Aber ich brauche dennoch Paarweise die Informationen. Also z.B. "SpielerName": "Costa", SpielerNummer": "7" usw..
Ich möchte beim Erstellen der XML ja auch eindeutig auf die Informationen zugreifen können.

So, jetzt meine Frage: wie soll ich das Lösen? Ich brauche einerseits eine Liste mit gleichen Inhaltsarten aber auch ein Key mit welchem ich direkt darauf zugreifen kann. Eine Liste scheint da am Sinnvollsten, aber wie mache ich das 1) im Dict als ein Value und 2) das ich die Informationen Paarweise habe und beim Zugriff darauf wie beim Dict mitteilen kann was ich haben will (also Name oder Position oder was auch immer)?
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

kaineanung hat geschrieben: Jetzt kommen die Spieler die ich auch in der Matchlist haben will. Da diese jedoch ein Dict ist kann ich als Key ja nicht einfach 'spieler' benutzen. Denn so würde ich nur einen, und zwar den letzten Spieler in der Liste haben da jeder update den vorherigen Spieler ersetzen würde.

Ich dachte ich hänge dann eine Liste in das dict an die 'value'-Stelle rein. Aber ich brauche dennoch Paarweise die Informationen. Also z.B. "SpielerName": "Costa", SpielerNummer": "7" usw..
Ich möchte beim Erstellen der XML ja auch eindeutig auf die Informationen zugreifen können.

So, jetzt meine Frage: wie soll ich das Lösen? Ich brauche einerseits eine Liste mit gleichen Inhaltsarten aber auch ein Key mit welchem ich direkt darauf zugreifen kann. Eine Liste scheint da am Sinnvollsten, aber wie mache ich das 1) im Dict als ein Value und 2) das ich die Informationen Paarweise habe und beim Zugriff darauf wie beim Dict mitteilen kann was ich haben will (also Name oder Position oder was auch immer)?
Entweder eine Liste von Tupeln (name, nummer) oder eine Liste von Dictionaries, ungefähr so:

Code: Alles auswählen

matchlist.update('heimteam', { ... , 'spieler': [('Costa', 7), ('Müller', 10), ('Neuer', 1) ... ] })
matchlist.update('heimteam', { ... , 'spieler': [ { 'SpielerName': 'Costa', 'SpielerNummer': 7 } ... ] })
Wobei es sich wahrscheinlich empfiehlt, den Wert für "spieler" außerhalb der update-Anweisung zusammenzubauen, sonst wird das sehr unübersichtlich und fehlerträchtig. In solchen Fällen hilft im übrigen die "setdefault"-Methode von Dictionaries oft weiter; unbedingt ansehen, falls sie Dir nicht eh schon gut bekannt ist.

Bei der Verschachtelung von Informationen, die Du ohnehin schon in Deinem Entwurf hast, würde ich aber auch darüber nachdenken, ob nicht doch eine oder mehrere Klassen statt des einen Dictionaries die Sache übersichtlicher machen würden.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaineanung: mir ist absolut nicht klar, was Du da wie speichern willst. Was steht denn in matchlist? Eine Liste, die per Update aktualisiert wird? Oder ist matchlist etwa ein Dictionary? Dann ist update falsch:

Code: Alles auswählen

matchlist['spielort'] = {...}
matchlist['heim_team'] = {...}
Was hat die Liga mit dem Spielort zu tun? Warum stehen die Spieler in matchlist? Die gehören doch zum Team. Und wenn Du eine bestimmte Reihenfolge einhalten willst, dann ist eine wirkliche Liste das richtige.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@bb1898

Eine Liste von... wird nicht gehen weil ich es ja in ein bereits vorhandenes dict reinbringen möchte.

Aber ich vermute ich habe dich lediglich nicht verstanden...

Ich habe ein Dict welches alle Informationen beinhaltet. Jetzt will ich dieses lediglich um eine Liste erweitern (im o.g. Beispiel um die Liste der Spieler).

Ist in deinem Beispiel die 'matchlist' nicht ein dict? Wenn ja, dann überschreibt doch der letzte den ersten wenn ich in beiden Fällen den Key 'heimteam' verwende.

Ich will in meinem 'Haupt'-Dict ein Satz hinzufügen. Meinem Beispiel folgend also eine Liste mit Spielern.
Der Key wird 'heimteam' genannt. Im Value sollte jetzt eine Liste kommen die alle Spieler beinhaltet jedoch 'direkt zugreifbar' -> name: Costa, nummer: 7...

Ich möchte am Ende also im o.g. Beispiel zugreifen können wie folgt:

Code: Alles auswählen

tmpdict = hauptdict['heimteam']
for spieler in tmpdict:
	print(tmpdict['name'])
	print(tmpdict['nummer'])
So daß ich dann eine Liste ähnlich dieser angezeigt bekomme:

Costa
7
Neuer
1
usw.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@Sirius

Ich habe mir geschwind halt einfach ein Beispiel ausgedacht und dabei die Logik der zusammengehörenden Daten nicht beachtet... darum ist es auch nur ein Beispiel.
Daher bitte nur so tun als ob Liga und Spielerort zusammengehören.. Ansonsten könnte ich ja statt dessen die Rasenbeschaffenheit speichern oder was anderes...

Es ist jedenfalls ein dict das ich befüllen möchte...
Im Beispiel also ein bereits gut befülltes dict welches ich mit den Spielen erweitern möchte.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaineanung: Dafür ist ein Dict die falsche Datenstruktur. Nimm eine Liste.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@sirius

Wie kann ich dann im Nachhinein die Werte dann genau zuordnen?
Bis zu der 'Spielerliste' hatte ich einen Key der für einen Datensatz stand.
Am Ende kann ich daraus irgendwas machen und an den entsprechenden Stellen dann die entsprechenden Werte aus dem Dict setzen.

Code: Alles auswählen

print("Heimteam: "+dictliste['heimteam']) # -> Heimteam: Bayern München
Mit einer Liste kann ich sowas nicht machen. Da habe ich die Daten so wie in der Reihenfolge hinzugefügt und das war es...
BlackJack

@kaineanung: Also ich habe ja ehrlich gesagt immer noch Verständnisschwierigkeiten mit dem was Du sagst/willst. Oder halt warum eine Liste nicht in Frage kommen soll. Denn wenn es mehrfach vorkommende Keys geben sollte, wie sollte *das* denn dann in der Benutzung aussehen‽ Das ist doch gerade der Witz bei einem Wörterbuch das einen Schlüssel ein Wert zugeordnet wird und das man über den Schlüssel diesen zugeordneten Wert abfragen kann. Wenn man einem Schlüssel einen anderen Wert zuordnet wird der vorherige ersetzt. Wäre das nicht der Fall und man hätte dann einen Schlüssel zweimal mit anderen Werten gespeichert was würde denn passieren wenn man dem Schlüssel noch etwas anderes zuordnet? Noch ein Schlüssel-Wert-Paar? Und wie würde man ausdrücken dass man eigentlich keine neue Zuordnung haben wollte sondern die vorhandene(n?) ersetzen wollte? Was passiert wenn man einen Schlüssel der mehrfach vorkommt abfragt? Wird dann zufällig einer der Werte geliefert? Oder eine Liste mit allen Werten? In dem Falle bräuchte man aber nichts spezielles neues sondern könnte bei den Wörterbüchern so wie sie existieren einfach alle Werte die zu einem Schlüssel gehören in einer Liste speichern.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Dir ist schon klar dass du belieibig weiter verschachteln kannst? Also die Spieler als Liste von Dictionaries repräsentieren kannst, wobei jedes Dictionary einen Spieler repräsentiert mit Name, Nummer usw.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@DasIch

Genau das meine ich. Ich habe ein Hauptdict das mit eindeutigen Schlüssel-Wertepaaren bestückt ist.
In einem Wert/Value würde ich gerne eine Liste haben. Aber nicht eine einfache Liste sondern eine (mehrdimensionale?) wo 3 Werte einen Datensatz bildet. Wert1: Name, Wert2 position und Wert3 irgendwas anderes.

Somit kann ich am Ende meines 'Durchgangs' auf die einzelnen Werte zugreifen über den Schlüssel und bei der Spielerliste eben über den Schlüssel 'heimteam'. Dieser liefert mir eine Liste die pro Spieler 3 Informationen der 11 Spieler beinhaltet.

@Blackjack
Das ist mir schon klar das ein Schlüssel eindeutig sein muss. Sonst ist er ja kein Schlüssel....
Aber ich suche eine Möglichkeit es zu verschachteln und vor allem was ich da verschachteln soll (siehe Oben -> Liste soll 3 Informationen/Datensatz enthalten).

Wenn ich das aber euch so erkläre, werde ich das Gefühl nicht los das es blödsinn ist und ich wohl doch am besten eine Klasse erstellen soll welche diese Werte speichern kann... ist zwar umfangreiche Arbeit aber machbar und 'einfacher' zu handhaben....
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@kaineanung: warum brauchst du eigentlich den Umweg über ein Dict und generierst nicht direkt den XML-Baum?

Gruß, noisefloor
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

kaineanung hat geschrieben:@DasIch

Genau das meine ich. Ich habe ein Hauptdict das mit eindeutigen Schlüssel-Wertepaaren bestückt ist.
In einem Wert/Value würde ich gerne eine Liste haben. Aber nicht eine einfache Liste sondern eine (mehrdimensionale?) wo 3 Werte einen Datensatz bildet. Wert1: Name, Wert2 position und Wert3 irgendwas anderes.
Mach es doch einfach. Ich versteh nicht wo du da ein Hindernis siehst.

Code: Alles auswählen

maindict = {
    'players': [
    	{'name': 'Hans Wurst', 'position': 1, 'whatever': 'spam'},
    	{'name': 'Max Mustermann', 'position': 2, 'whatever': 'eggs'},
    	...
    ],
    'other': ...
}
In XML würde man es schliesslich auch so machen:

Code: Alles auswählen

<root>
    <players>
        <player name="Hans Wurst" position="1" whatever="spam" />
        <player name="Max Mustermann" position="2" whatever="eggs" />
    </players>
</root>
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@DasIch

Genau das habe ich gesucht.

Also, ich habe ein Dict mit dem Key 'players'.
Dieses Element füge ich dem Hauptdict mit der Update-Methode an.
Diesm gebe ich eine Liste mit dessen Elemente wiederrum aus einzelnen Dicts besteht.

Ich kreiere die einzelnen Dicts und 'appende' in eine Liste. Das Endergebnis dann per 'update' in den Hauptdict, richtig?

Und wie sieht der Zugriff dann auf die Daten aus?

Code: Alles auswählen

for element in maindict['players']:
	print(element['name'])
@noisefloor
Ich habe bereits einen ersten Entwurf wo ich das direkt in XML speichere.
Ist aber ziemlich unübersichtlich wenn ich mit den Nodes-Ebenen der Subelemente hantieren muss vor jedem neuen XML-Node.
Wenn ich da jetzt eine Änderung vornehmen muss ist es kompliziert.
Daher dachte ich mir: ich mache ein dict und am Ende mache ich an einer Stelle die ganze XML-Arbeit. Dann kann ich noch Dinge ändern falls aufgrund diverser Nodes die Bedingungen für andere Nodes sich ändern.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@DasIch

Super! Es hat genauso geklappt!
Ich greife nun auf die einzelnen Werte direkt zu indem ich den Key des Hauptdicts angebe, dann ein Listindex und dann wiederrum den Key der entsprechenden Info die ich haben will.

Also genau das was ich gesucht habe und sicherlich werde ich auch iterieren können über die Liste hinweg (habe ich zwar noch nicht ausprobiert aber 3warum sollte das nicht gehen, ist ja eine Liste..).

Danke dir!

@all

Danke euch!
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Dafür gibt es übrigens collections.defaultdict.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Antworten