Arbeiten mit Dictionary und Lists Objekten

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
Shakreo
User
Beiträge: 4
Registriert: Donnerstag 27. Oktober 2011, 07:50

Hallo,

ich arbeite momentan an einem Projekt, durch das ich mit meinem ersten Python Skript konfrontiert werde.
Durch Erfahrungen in anderen Programmiersprachen viel mir Einstieg recht leicht, allerdings bin ich gerade auf ein Problem gestoßen.

test = backend.getHardwareInformation_hash(hostId = "hostId")

Diese Funktion liet in der python-opsi Library und gibt mir ein Dictionary Object zurück.

str(test.keys()) hat folgende Ausgabe:

Code: Alles auswählen

[u'DISK_PARTITION', u'COMPUTER_SYSTEM', u'VIDEO_CONTROLLER']
In meinem speziellen Fall will ich auf das Objekt COMPUTER_SYSTEM zugreifen:

str(test[u'COMPUTER_SYSTEM']) hat dann folgende Ausgabe:

Code: Alles auswählen

{u'vendor': u'Dell Inc.', u'model': u'OptiPlex 780'}
Und dort will ich auf das Objekt 'model' zugreifen. Aber wie genau mache ich das an dieser Stelle?

Wenn ich test[u'COMPUTER_SYSTEM'][u'model'] verwende bekomme ich den Fehler:
List Indices must be integer, not unicode.

Ein bisschen recherchiert und herausgefunden, dass ich Lists nur mit dem Zahlen Index ansprechen kann. Ok, nachgezählt, Wert steht an 6. Stelle (oben ist die Ausgabe nur etwas gekürzt, zwecks Lesbarkeit)
List Index out of range
Bisschen rumgetestet, mal IndexNr. 1 genommen:
List Index out of range -.-

Vielleicht könnt ihr mir ja ein bisschen auf die Sprünge helfen, ich komme gerade nicht wirklich weiter.

Vielen Dank schonmal

Gruß Shakreo

Edit sagt: Eben nochmal probiert weil ich ganz vergessen hatte, dass der erste Index ja die 0 ist -.-
Wenn ich mir das ausgeben lasse, erhalte ich wieder die selbe Ausgabe wie bei str(test[u'COMPUTER_SYSTEM'])
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Einfach mal ins blaue geraten: Kann es sein, dass du eine ein-elementige Liste erhältst?
Versuch dann einen Indexzugriff 0.

Aber das Aufrufen von `str` verwundert mich, warum machst du das? dict.keys liefert eine Liste zurück. Die kannst du direkt ausgeben und musst sie nicht über str erst umwandeln.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
BlackJack

@Shakreo: Also ich hab's mir jetzt zweimal durchgelesen und bin beide Male zu dem Schluss gekommen, dass die Fehlermeldung nicht zu Deinem Quelltext passt. Das was Du bei ``test['COMPUTER_SYSTEM']`` sieht nicht nach einer Liste sondern nach einem weiteren Wörterbuch aus. Zeig doch mal was `type()` zu diesem Objekt sagt.
Shakreo
User
Beiträge: 4
Registriert: Donnerstag 27. Oktober 2011, 07:50

Ja ich weiß, das ist schon alles ziemlich chaotisch.

Anfangs dachte ich ja auch, das 2. Objekt wäre vom Typ Dict, allerdings sagt ja die Fehlermeldung an der Stelle:
List Indices must be integer, not unicode.

Code: Alles auswählen

type('test[u'COMPUTER_SYSTEM'])
<type 'list'>
Und scheinbar scheint es wirklich eine liste zu sein, die nur ein Element enthält... Die Funktion len() gibt mir den Wert 1 zurück -.-

Ich wäre ja schon froh, wenn die Opsi Library dokumentiert wäre, aber das ist an der Stelle etwas bescheiden, bzw nicht vorhanden.
Ich habe gestern mindestens 3 Std lang gesucht, um überhaupt die Funktion zum auslesen des Dict Objektes zu finden. Irgendwann habe ich es dann geschafft in der hintersten Ecke des System die Datei zu finden in der die Funktionen definiert werden ;)

Btw warum ich oft die Funktion str() verwende. Ohne diese Funktion habe ich recht oft die Fehlermeldung
'Cannot concatenate String with list Objekt' bekommen. (Oder so ähnlich)

Edit: Naja ich habe mein Problem jetzt erstmal mit Hilfe der Split() Funktion gelöst. Zwar etwas unschön, aber anders scheint es nicht zu gehen.
deets

Ich denke, du hast immer noch nicht ganz verstanden, wie genau deine Datenstruktur aussieht.

Statt da immer mit Schluesseln und str() zu fummeln, lass sie dir doch mal mit

import pprint
pprint.pprint(struktur)

ausgeben. Und zeig uns das Ergebnis.

Denn mit deinem String-gesplitte landest du ganz schnell in Teufels Kueche, wenn da Kommata in den Daten vorkommen.
Shakreo
User
Beiträge: 4
Registriert: Donnerstag 27. Oktober 2011, 07:50

Wenn ich ganz ehrlich bin, habe ich das auch noch nicht so ganz.
Der Grund den du gerade genannt hast, ist auch der, warum ich das unschön finde.

Welchen Rückgabewert hat denn diese Funktion, bzw kann die Funktion so ausgeführt werden, so dass ich einen String zubekomme?

Weil die Vorgehensweise nach der ich hier vorgehen muss ist allerdings genauso chaotisch.

Ich versuche mal kurz zu beschreiben, wie jeder Testlauf aussieht.

Erstmal von Anfang an. Mit Hilfe von Opsi kann man unter anderem Betriebssysteme automatisiert verteilen, genau das was ich vorhabe.
Innerhalb des Produktes Windows7 gibt es eine Setup.py, die zur Vorbereitung auf dem client ausgeführt wird, mit Hilfe eines Linux, dass übers Netzwerk auf dem Client gebootet wird.

Mein Problem an der Stelle ist, dass die Setup.py nur dann funktioniert, wenn Sie im richtigen Kontext aufgerufen wird (mal ganz abgesehen davon, dass dort auch jedes Mal die Platte formatiert wird, wäre es nicht sinnvoll diese an einer anderen Stelle auszuführen)
Das 2. Problem ist, dass ich an der Stelle auch keine Textausgabe machen kann (zumindest erscheint diese nicht ;) )

Allerdings habe ich die Möglichkeit meine Ausgabe mit dem Befehl logger.notice() einen Eintrag in der logfile zu hinterlegen, wo ich dann jedes Mal meine Ausgabe kontrollieren kann...

Das nur mal so um meine Rückfrage zu begründen ;)
deets

Ich finde deinen Post auesserst schwer verstaendlich. Da scheinen ganze Worte zu fehlen, und wirklich schlauer als vorher bin ich auch nicht.

Und was deine Frage nach der alternativen Ausfuehrung der Funktion angeht - das kann dir ausser der Dokumentation der Software keiner beantworten. Aber es waere auesserst ungewoehnlich, wenn sich ein Aufruf nach den Wuenschen eines Anwenders richtet...

Was auch immer du gemacht hast um vorher an die hier gezeigten Daten-Struktur-Dumps zu kommen, kannst du auch mit pprint machen. Falls du pprint nicht verwenden kannst, weil du einen logger verwenden musst, kannst du stattdessen auch pprint.pformat benutzen - das liefert fuer eine komplexe Datenstruktur einen String, statt ihn gleich mittels print auf sys.stdout auszugeben (wie es pprint tut).

Probier es erstmal mit der Konsole und irgendwelchen eigenen Testdaten aus - und dann mach das doch mal bitte an genau der Stelle, wo du vorher den ..keys()-Kram gemacht hast, bevor du dich in die Struktur runterhangelst.
Shakreo
User
Beiträge: 4
Registriert: Donnerstag 27. Oktober 2011, 07:50

Ja ich, das ist alles ziemlich chaotisch.

Das mit der alternativen Ausführung war vielleicht auch etwas falsch ausgedrückt. Meinte da eher eine Alternative Funktion.
pformat war also genau das was ich gesucht habe.

Ein eigenes Objekt zum testen bringt mir in deswegen nichts, weil ich ja eben herausfinden muss, wie das Objekt test aufgebaut ist. Und das gibt mir eine vorgefertigte Funktion zurück.
Eine Dokumentation dazu fände ich auf jeden Fall auch schön, allerdings ist meine nachfrage im offiziellen Forum seit 3 tagen unbeantwortet, weshalb ich davon ausgehe, dass es keine gibt ;)

Das einzige, wo ich mir sicher bin ist, mir qualmt der Schädel ^^

Ausgabe von pformat(test):

Code: Alles auswählen

 {u'CHASSIS': [{u'chassisType': u'space-saving',
               u'description': u'Space-saving Computer',
               u'installDate': None,
               u'name': u'space-saving',
               u'serialNumber': u'9PFQZ4J',
               u'type': u'AuditHardwareOnHost'}],
 u'COMPUTER_SYSTEM': [{u'description': u'Space-saving Computer',
                       u'model': u'OptiPlex 780',
                       u'name': u'kr-test',
                       u'systemType': u'space-saving',
                       u'totalPhysicalMemory': 4294967296L,
                       u'type': u'AuditHardwareOnHost',
                       u'vendor': u'Dell Inc.'}],
 u'DISK_PARTITION': [{u'description': u'Windows NTFS volume',
                      u'driveLetter': None,
                      u'filesystem': u'Windows NTFS volume',
                      u'freeSpace': None,
                      u'index': 1,
                      u'name': u'/dev/sda1',
                      u'size': 64428585984L,
                      u'startingOffset': None,
                      u'type': u'AuditHardwareOnHost'},
                     {u'description': u'Windows NTFS volume',
                      u'driveLetter': None,
                      u'filesystem': u'Windows NTFS volume',
                      u'freeSpace': None,
                      u'index': 2,
                      u'name': u'/dev/sda2',
                      u'size': 185570542080L,
                      u'startingOffset': None,
                      u'type': u'AuditHardwareOnHost'}]}
Wieder aufgrund von Lesbarkeit gekürzt.

Edit:

Soo an der Stelle vielen Dank, für diesen tollen Befehl, Problem gelöst mit einer vieeel besseren Variante

Code: Alles auswählen

test[u'COMPUTER_SYSTEM'][0][u'model']
Innerhalb des list Object war noch ein Dict Object versteckt ;)
Antworten