Dict: Multi-Values

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
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Hallo miteinander,
ich habe ein kleines Problem. Und zwar folgendes:
Mithilfe meines Programmes lassen sich die RGB-Werte aus einer Datei lesen.
Der Aufbau des Programmes sieht so aus, dass ich die R-Werte zuerst in x-Richtung auslese, dann die selben Pixel in x-Richtung wieder von vorne um den G-wert zu bekommen. Und das gleiche nochmal mit den B-Werten.

Was ich nun möchte ist, dass ich ein Dictionary habe, welches sich die RGB-Werte nach jedem Durchlauf als Value hinzufügt.
Hier ein kleines Bsp:

Code: Alles auswählen

dict = {None, None, None}
for i in range(18):
    if i <= 6:
        dict["x-y"] = {i, None, None}
    elif i <= 12:
        dict["x-y"] = {None, i, None}
    elif i <= 18:
        dict["x-y"] = {None, None, i}
Im Schleifendurchlauf 1 (i<=6) soll ein Wert als 1.Value im Dictionary gespeichert werden. In Durchlauf 2 als 2. Stelle. Und in Durchlauf 3, an dritter Stelle.
Quasi sowas:

Durchlauf 1:
d[x,y] = {color, None, None}
in Durchlauf 2 für die selbe Koordinate:
d[x,y] = {color(aus durchgang 1), color, None}
Und in Durchlauf 3 dann:
d[x,y] = {color(aus durchgang 1), color(aus durchgang 2), color}

sodass am Ende das z,b. in der Ausgabe steht:
d = {(1|1): 255|255|255, (1|2): 255|255|255, (1|3): 0|0|0, ...}
Als Key steht die entsprechende Bild-Koordinate, und im Value die 3 RGB-Werte.

Wie muss ich das Dictionary definieren und wie sieht der richtige Code aus, um die Werte an Stelle 1-3 einzuspeichern?
Ich hoffe die Aufgabenstellung ist präzise genug... Auch ich war Anfangs total überfordert.
Danke für die Hilfe! :)
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Python93 hat geschrieben: Der Aufbau des Programmes sieht so aus, dass ich die R-Werte zuerst in x-Richtung auslese, dann die selben Pixel in x-Richtung wieder von vorne um den G-wert zu bekommen. Und das gleiche nochmal mit den B-Werten.
Ist das wirklich notwendig? Kann man die Arbeit nicht auch "parallel" in einem Durchlauf erledigen? Wenn ja, solltest Du das umstellen, da Du damit um den Faktor 3 schneller wirst ;-)

Python93 hat geschrieben: Im Schleifendurchlauf 1 (i<=6) soll ein Wert als 1.Value im Dictionary gespeichert werden. In Durchlauf 2 als 2. Stelle. Und in Durchlauf 3, an dritter Stelle.
Äh... hier zeigst Du im Code etwas anderes, als Du es beschreibst! Du hast hier genau *eine* Schleife ergo *einen* Durchlauf!

Hier solltest Du noch mal nachdenken, ob das alles bei Dir wirklich zusammen passt.
Python93 hat geschrieben: d = {(1|1): 255|255|255, (1|2): 255|255|255, (1|3): 0|0|0, ...}
Als Key steht die entsprechende Bild-Koordinate, und im Value die 3 RGB-Werte.
Wie willst Du denn später auf die Werte zugreifen?

Ich habe im Moment das Gefühl, dass ein Dictionary da keine ideale Datenstruktur ist, denn Du willst doch sicherlich für jeden Bildpunkt einen RGB-Wert hinterlegen, oder?

Wenn ja, würde ich eine Liste von Listen nehmen:

Code: Alles auswählen

colormap = [
    [[255, 255, 255], [255, 255, 255], [0, 0, 0]], # 1. Zeile
    [[255, 255, 255], [0, 0, 0], [255, 255, 255]], # 2. Zeile
    [[0, 0, 0], [255, 255, 255], [255, 255, 255]], # usw.
]
Damit kannst Du dann intuitiv via Index auf die einzelnen Elemente zugreifen:

Code: Alles auswählen

colormap[2][0] # 3. Zeile, 1. Bildpunkt
Zudem sind Listen im Gegensatz zu Dictionaries fix in der Reihenfolge, so dass Du die Punkte leicht in der richtigen Reihenfolge durchgehen kannst.

Wenn Du natürlich nicht für jeden Bildpunkt eine Angabe hast, dann wäre evtl. doch ein Dictionary von Dictionaries geeignet, da Du dann eine dünn besetzte Matrix effizienter speichern kannst.

Mir erscheint das auf jeden Fall besser, als Deine Idee eines Zugriffs mittels eines "kryptischen", erst zu berechnenden Schlüssels!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Python93: Arbeite am besten mal ein Tutorial durch um die richtige Syntax für literale Wörterbücher (und Listen (und Zeichenketten)) zu lernen und was diese Datentypen an Operationen anbieten.

Und dann musst Du Dir klar werden welche Datentypen Du kombinieren musst. Davon abgesehen, dass ``{None, None, None}`` keine Syntax ist mit der man ein Wörterbuch definiert, ist das sicher nicht initiale Wert für das Gesamtergebnis. Die einzelnen Werte für ein Pixel möchtest Du auch gar nicht in einem Wörterbuch, sondern in einer Liste speichern. Und die musst Du auch nicht mit Werten (`None`) vorbelegen, die Du im Laufe des Programms mit den tatsächlich benötigten Werten ersetzt, sondern Du kannst mit einer leeren Liste starten und die Werte dort anhängen.

Für das Gesamtergebnis würde ich ein Wörterbuch als Datenstruktur auch in Frage stellen. Es sind doch vollbesetzte, zweidimensionale Daten mit den Koordinaten als „Schlüssel”, warum also nicht eine verschachtelte Listenstruktur?

Liegen die Daten in der Datei in dieser Form vor, dass erst alle Rotwerte, gefolgt von allen Grünwerten, und dann allen Blauwerten gespeichert sind? Was ist denn das für ein Format? Vielleicht gibt es ja schon eine Bibliothek um das effizient einzulesen‽
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Das kann ich machen.
Ich les mir diverse Tut's durch...
Das Format .pcx ist nunmal so. Da sind die Bilddaten so eingepackt:
x|y Wert
1|1 R 255
1|2 R 255
1|3 R 0
1|1 G 0
1|2 G 255
1|3 G 255
1|1 B 0
und so weiter...

Istn bisschen doof, aber man kann zum Ziel kommen.
Ich dachte nur wenn man so 'Koordinate->Wert' Paarungen hat bietet sich ein Dictionary an.
Bin halt doch noch ein Python-Noob :)
danke für die Hilfe BlackJack

@Hyperion:

Ja bei mir passt alles, ich habe die Schleifen schon passend. Soweit funktioniert alles. Ich brauche nur noch die richtige Datenstruktur. Und als Anfänger hat sich mit natürliche in Dictionary angeboten.
Das mit den Listen ist ne gute Idee. Ich probier mal etwas rum und melde mich dann wieder. Danke dir auch ! :)
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Python93 hat geschrieben: Das Format .pcx ist nunmal so. Da sind die Bilddaten so eingepackt:
x|y Wert
1|1 R 255
1|2 R 255
1|3 R 0
1|1 G 0
1|2 G 255
1|3 G 255
1|1 B 0
Sieht das in der Datei *exakt* so aus? Und hast Du nicht mal geguckt, ob `pil` das schon kann? ;-)

Python93 hat geschrieben: @Hyperion:

Ja bei mir passt alles, ich habe die Schleifen schon passend.
Irgend wie ja nicht! Denn ich sehe bei Dir nur *eine* Schleife und ausgehend von Deiner Beschreibung des Formates braucht man auch nur *eine* Schleife!

Insofern passt es nicht zusammen, wenn Du dauernd von *Schleifen* oder *Durchläufen* redest... da wäre der Singular passend zum Code.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Python93: Die „Python Imaging Library” (PIL) kann das PCX-Format lesen:

Code: Alles auswählen

In [24]: from PIL import Image

In [25]: img = Image.open('test.pcx')

In [26]: img.getpixel((23, 42))
Out[26]: (227, 226, 224)
Python93
User
Beiträge: 36
Registriert: Mittwoch 13. Juni 2012, 07:50

Ich habe Vorgaben von meinem Ausbilder. Die besagen zum Beispiel, dass das ganze mit .pcx-Dateien gemacht werden muss, oder dass ich so wenig fertige Funktionen wie möglich verwenden soll.
Das heißt auch PIL nicht... Das hat mein Ausbilder bewusst so gemacht, denke ich.

Und meine Schleifen in meinem Code passen. Was ich hier reingeschrieben habe, war nicht auf mein Programm bezogen, sondern eher allgemein auf Dictionarys. Sonst hätte ich den Thread-Name anders gewählt.

Wie gesagt, ich probiere mich mal mit Listen und dann melde ich mich nochmal.
Danke nochmal für die Hilfe.
Ich benutze:
- Python 2.7
- Windows XP
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Python93 hat geschrieben:Ich habe Vorgaben von meinem Ausbilder.
So etwas solltest Du immer erwähnen! Dann kann man sich nämlich ggf. Hinweise auf (sinnvolle) Libs sparen oder man würde Dich zumindest nicht ausschließlich damit "abspeisen" ;-)
Python93 hat geschrieben: Und meine Schleifen in meinem Code passen.
*facepalm* Du hast hier in diesem Thread Code und Beschreibungen geliefert, die *nicht* zueinander passen. Das ist ein Faktum und nicht weg zu diskutieren. Es mag ja sogar sein, dass Du in Deinem richtigen Code *mehrere* Schleifen hast - hier zeigst Du nur *eine* und sprichst dennoch im Plural... da ist es doch logisch, dass uns das auffällt und man da nachfragt.

Im übrigen sehe ich bei dem gezeigten Format immer noch keine Notwendigkeit, *mehrere* Schleifen zu verwenden. Das Parsen lässt sich - ausgehend von Deiner Formatbeschreibung - definitiv in einem Durchlauf erledigen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten