komplexes Dict

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
bruZard
User
Beiträge: 3
Registriert: Montag 20. August 2012, 17:52

Hallo, ich bin ziemlich neu bei Python und habe da natürlich auch Fragen. Meine erste konnte ich auch mit der Suchfunktion nicht wirklich beantworten.

Ganz speziell möchte ich ein Python Script für Blender schreiben welches Daten für Monkey/miniB3D exportiert. In diesem Zusammenhang benötige ich etwas wie dieses hier:

Code: Alles auswählen

brus{
	0{
		name	: 'nameDesBrush', 
		diffuse	: [1.0, 1.0, 1.0],
		specular: [1.0, 1.0, 1.0], 
		alpha	: 1.0,
		texID	: [0, 2, 3]
	}
}
Habe es mit einem Dictionary versucht, aber nun weiß ich nicht wie ich unter der ID "0" weitere Handles anlegen kann.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was ist denn das für ein Code? Das soll hoffentlich kein Python sein, oder doch? (Da fehlen mindestens zwei Doppelpunkte!)

Ich weiß jetzt nicht, was ein `Handle` ist, aber wenn es sich bei Dir um ein Dictionary von Dictionaries handeln sollte, dann greife eben auf das innere per Schlüsselzugriff zu und füge diesem dann einen Eintrag hinzu.

Hier mal ein simples Beispiel:

Code: Alles auswählen

d = {
    "foo": {
        "bar": 42
    }
}

d["foo"]["foobar"] = "Noch ein Wert"

>>> {'foo': {'bar': 42, 'foobar': 'Noch ein Wert'}}
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
bruZard
User
Beiträge: 3
Registriert: Montag 20. August 2012, 17:52

Das ist kein Python Code, sondern ein JSON ;)

Präziser:

Ich habe ein Array und eine lokale Variable die ich inkrementiere. Diese lokale Variable stellt das obige "0{" dar. Ich benötige also ein Dict in einem Dict (das klappt schon) in welchem wiederum Indizes auf ein Array verweisen können.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sorry, aber so wird das nichts. Zeig uns doch mal die Ausgangsdaten und dann die gewünschte Zielstruktur. Zudem gerne auch Code, den Du schon hast. Wir müssen schon wissen, *was* Du für Daten hast und *wie* diese transformiert werden sollen.

Edit: Ich weiß jetzt nicht, wie streng oder lacks JSON definiert ist, aber mit dem `json`-Modul von Python kann ich das obige nicht einlesen ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@bruZard Wenn Du Hilfe bei der Erzeugung von JSON haben möchtest, dann musst Du uns schon auch gültiges JSON zeigen. Dein Beispiel ist kein gültiges JSON, und Du hast auch nicht anderweitig erklärt, aus welchen Ausgangsdaten Du welche JSON-Serialisierung erzeugen möchtest. Wie sollen wir Dir mit so wenig Informationen sinnvoll helfen? Wir können auch nur ins Blaue hineinraten. Das tue ich jetzt mal, und hoffe, dass ich damit nicht allzu weit von Deinem eigentlichen Problem entfernt bin:

Ich gehe davon aus, dass Du irgendwelche Daten in Form von Wörterbüchern in einer Liste („Arrays“ gibt es in Python, aber die wirst Du wohl kaum verwenden) vorliegen hast, und diese jetzt nach JSON serialisieren möchtest. Da stellt sich zuerst die Frage, ob Du überhaupt eine explizite Abbildung von Index zu Element brauchst. Wenn nicht, dann kannst Du einfach die Liste selbst serialisieren. Bei der Deserialisierung erhältst Du die gleiche Liste mit identischer Reihenfolge wieder zurück, so dass die Daten alle wieder an den Indizes liegen, an denen Du sie erwartest. Falls Du doch eine explizite Abbildung benötigst, dann kannst Du eine Liste einfach mit "dict(enumerate(l))" – wobei "l" die entsprechende Liste ist – in ein Wörterbuch umwandeln, dass die Indizes der Elemente auf das entsprechende Element abbildet.

Ich hoffe, dass hilft Dir. Wenn nicht, dann ist es an Dir, Dein Problem so zu erklären, dass wir es verstehen können, ohne raten zu müssen.
bruZard
User
Beiträge: 3
Registriert: Montag 20. August 2012, 17:52

Hmm, kompliziert ;)

Also: Das JSON da oben habe ich aus dem Ärmel geschüttelt, es ist schon möglich dass es nicht valide ist. Es steht auch noch nicht fest dass das so gelöst werden soll (wahrscheinlich nicht). Grundlage meines Versuches ist die Definition des binären Formates B3D, welches man hier nachlesen kann, nach JSON zu transportieren damit man aus Blender heraus 3D Models für Monkey/miniB3D erzeugen kann. Monkey/miniB3D ist eine Adaption von Blitz3D für Monkey welches es gestattet ohne Source-Änderung für diverse Targets zu programieren (HTML5, Android, iOS, XNA etc.).

Mein derzeitiges Problem ist: Wie platziere ich ein dict in einem dict? Folgendes funktioniert leider nicht:

Code: Alles auswählen

foo = {}
foo['brus'][currentID]['diffuse'] = [1.0, 1.0, 1.0]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mir ist immer noch nicht klar, was Du da genau machen willst. Kannst Du das nicht auf eine Domänen unabhängige Darstellung herunterbrechen? Ich habe ehrlich gesagt keine Lust, mir eine Spezifikation für ein mir unbekanntes Format durchzulesen. Zudem bringt mir das ja nichts, da ich das Zielformat damit immer noch nicht kenne ;-)

Zu Deiner Frage: "Funktioniert nicht" nützt gar nichts! Poste die *exakte* Fehlermeldung des Interpreters stets mit dem Code, der sie bewirkt.

In diesem Falle ist es aber auch so erkennbar: Du erstellst ein leeres Dictionary und willst aber nicht diesem, sondern irgend einem Objekt, welches bereits das zweite Dict im Dict wäre, einen Wert zuweisen. Das geht natürlich nicht!

Du kannst erst einmal nur `foo['brus']` etwas zuweisen. Wenn das dann wieder ein Dictionary sein soll, also z.B. so:

Code: Alles auswählen

foo['brus'] = dict()
Du kannst natürlich auch gleich mittels Literalen eine solche verschachtelte Datenstruktur bauen:

Code: Alles auswählen

foo = {{{}}}
Damit kannst Du dann Deine Zuweisung ausführen.

Das sind aber alles simple Python Grundlagen. Da Du diese offenbar nicht beherrschst, solltest Du Deine Ansprüche wohl erst ein wenig zurückstellen und ein Tutorial durcharbeiten, i.A. wird hier das offizielle (in der Doku integrierte) empfohlen.

Für das Parsen von binären Formaten gibt es zudem Module, die einem das Leben erleichtern. Mir fältt aber mal wieder der Name dieses einen nicht ein, welches hier schon öfter Thema war... da musst Du ggf. mal die SuFu benutzen oder auf BlackJack hoffen, der genau weiß, was ich meine :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Code: Alles auswählen

from collections import defaultdict

chaineddict = lambda: defaultdict(chaineddict)

foo = chaineddict()

currentID = 42

foo['brus'][currentID]['diffuse'] = [1.0, 1.0, 1.0]

import json
print json.dumps(foo)
Suchst du sowas?
[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

@Hyperion: Hoffst Du vielleicht das ich `construct` in diesem Zusammenhang erwähne? :-)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ach Mensch... mir lags auf der Zunge :D Aber genau das ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Du kannst natürlich auch gleich mittels Literalen eine solche verschachtelte Datenstruktur bauen:

Code: Alles auswählen

foo = {{{}}}
Damit kannst Du dann Deine Zuweisung ausführen.
Interessant in welcher Sprache, denn in Python brauchts einen Key :p Wobei ich die Fehlermeldung einigermaßen spannend finde, denn ich hätte auf SyntaxError getippt, aber raus kommt ein TypeError. Vermutlich ist die Grammatik nicht so streng sowas direkt zu verbieten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
deets

Noe, das waere nur die Menge mit der Menge die nur ein leeres Dict als Element hat - aber weil weder dicts noch sets hashbar sind, geht das halt nicht, was aber erst zur Laufzeit auffaellt :)
BlackJack

Nee, das ist ein `SyntaxError`. Zumindest bei Python 2.6 :-)

Code: Alles auswählen

In [87]: {{{}}}
------------------------------------------------------------
   File "<ipython console>", line 1
     {{{}}}
         ^
SyntaxError: invalid syntax
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Mit Python 2.7 und Set-Literalen aber nicht mehr ;)
deets

BlackJack ist sooooo 2008...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben: Interessant in welcher Sprache, denn in Python brauchts einen Key :p
:oops:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten