Seite 1 von 1
Tuple kurz in Liste verwandeln
Verfasst: Montag 24. August 2009, 15:42
von Apothecarius
Hallo
Ich hab eine kleine Frage:
Ich arbeite grade an einem Sudokugenerator (besser gesagt Version 2.0)
Für die Zahlenfelder benutze ich 9 Listen in einem Tuple (früher waren es nur Listen, aber Tuple seien ja besser fürn Speicher)
Wenn ich jetzt eine ganze Zeile überschreiben will habe ich den Code
Code: Alles auswählen
feld = list(feld)
feld[index] = over
feld = tuple(feld)
return
Würde dies Sinn machen, das Programm von Liste-Liste auf Tuple-Liste umzuschreiben?
Denn: Könnte es sein, dass der Speichergewinn durch diese zwischenzeitliche Umwandlung effektiv nicht gebraucht werden kann?
Verfasst: Montag 24. August 2009, 15:51
von Rebecca
Mach ne Liste von Listen. Du willst ein Sudoku ja staendig aendern, und Listen sind da nunmal die geeignete Datenstruktur.
Was seine Sorgen wg. des Speicherverbrauchs betrifft: "Premature optimisation is the root of all evil". Du machts deinen Code schlechter lesbar fuer einen Effekt, den du eh nicht merken wirst. Mal erhlich, 9x9 (oder seien wir grosszuegig, 16x16 fuer ein grosses Sudoku) Felder sind nichts. Selbst wenn wuerdest du dir duch das hin- und herkonvertiere Performance-Nachteile einhandeln...
Verfasst: Montag 24. August 2009, 15:53
von EyDu
Hallo,
du solltest dir um Speicher und Geschwindigkeit keine Gedanken machen, davon ist meistens genug da. Ich würde den Ansatz mit den Listen sein lassen und das Spielfeld als Dictionary erzeugen. Als Schlüssel benutzt du dann die Koordinaten in Form von Tupeln (x, y).
Vielleicht noch ein Tipp für die Implementierung: Erstelle allgemeine Generatoren für Zeilen, Spalten und die 3x3 Felder, damit kannst du dir eine Menge Arbeit sparen.
Verfasst: Montag 24. August 2009, 16:03
von Apothecarius
@Rebecca
ok thx dann bleib ich bei List-List.
@EyDu
für die 9er Gruppen hab ich schon n getter geschrieben damit ich diese Gruppen einzeln behandeln kann, das Codestück oben ist aus dem entsprechenden Setter dazu.
Die Dictionary Idee klingt interessant, aber ich glaube da müsste ich schon ne Menge umschreiben, denn eigentlich ist das Programm schon fertig, nur eben etwas noobig geschrieben (in statement ignoriert

)
Verfasst: Montag 24. August 2009, 16:39
von Rebecca
Ich denke mal, ein dictionary wuerde sich auch erst lohnen, wenn man sogennante "sparse"-Besetzungen hat, also wenn man viel mehr Felder ohne Information hat als welche mit Information, sodass man die leeren Felder nicht alle speichern muss.
Verfasst: Montag 24. August 2009, 16:43
von Apothecarius
Im Programm werden die Möglichkeiten direkt im Feld gespeichert, ein Set(war früher auch eine Liste) mit allen Möglichkeiten, wenn es noch nicht sicher ist , ein Integer wenn die Zahl rausgefunden wurde
Wie ist das mit "Tuple nicht so wichtig" denn bei Programmen die auf Leistung optimiert werden sollten.(zB Anspruchsvolle Spiele oder Renderprogramme)
Sollte ich da (zB) für mitgegebene Werte lieber Tuples statt Listen benutzen, wenn ich die Mitgabewerte nicht komplett verwende?
Verfasst: Montag 24. August 2009, 17:13
von EyDu
Rebecca hat geschrieben:Ich denke mal, ein dictionary wuerde sich auch erst lohnen, wenn man sogennante "sparse"-Besetzungen hat, also wenn man viel mehr Felder ohne Information hat als welche mit Information, sodass man die leeren Felder nicht alle speichern muss.
Ich benutze sie einfach weil ich faul bin. spam[x, y] lässt sich viel schöner lesen und schreiben als spam[x][y].
Verfasst: Montag 24. August 2009, 20:44
von audax
EyDu hat geschrieben:Rebecca hat geschrieben:Ich denke mal, ein dictionary wuerde sich auch erst lohnen, wenn man sogennante "sparse"-Besetzungen hat, also wenn man viel mehr Felder ohne Information hat als welche mit Information, sodass man die leeren Felder nicht alle speichern muss.
Ich benutze sie einfach weil ich faul bin. spam[x, y] lässt sich viel schöner lesen und schreiben als spam[x][y].
Dann überschreib halt __getitem__
Code: Alles auswählen
class NestedList(list):
def __getitem__(self, index):
try:
ret = self
for idx in index:
ret = list.__getitem__(ret, idx)
return ret
except TypeError:
return list.__getitem__(self, index)
Code: Alles auswählen
>>> x = NestedList([[1,2,3],[2,3,4]])
>>> x[1]
[2, 3, 4]
>>> x[1,1]
3
>>> x[0,0]
1
>>> x[1,2]
4
Verfasst: Montag 24. August 2009, 20:57
von EyDu
Sehr praktisch, so werde ich es jetzt bestimmt immer machen

Verfasst: Dienstag 25. August 2009, 08:02
von audax
Code: Alles auswählen
class NestedList(list):
def __getitem__(self, index):
reraise = False
try:
ret = self
for idx in index:
try:
ret = list.__getitem__(ret, idx)
except TypeError:
reraise = True
raise
return ret
except TypeError:
if reraise:
raise
return list.__getitem__(self, index)
Muss man doch so machen, da sonst bei x = [[1,2],[3,4]]; x[0,1,2] der falsche TypeError kommmt

Re: Tuple kurz in Liste verwandeln
Verfasst: Donnerstag 27. August 2009, 23:16
von birkenfeld
Apothecarius hat geschrieben:
Für die Zahlenfelder benutze ich 9 Listen in einem Tuple (früher waren es nur Listen, aber Tuple seien ja besser fürn Speicher)
OT: Noch kleiner sind für Container mit fixer Anzahl Elemente übrigens Klassen mit __slots__:
Code: Alles auswählen
>>> import sys
>>> sys.getsizeof([1,2])
88
>>> sys.getsizeof((1,2))
72
>>> class O(object):
... __slots__ = ('a', 'b')
...
>>> o = O()
>>> o.a = 1
>>> o.b = 2
>>> sys.getsizeof(o)
64
Das Problem ist nur, dass jetzt das __getitem__ furchtbar aufwändig wird.
(Außer man schreibt das Äquivalent gleich in C.)