Dynamische Teillisten

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
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Ich möchte eine große Liste (gl) mit 100 items definieren, und eine kleine Liste (kl) mit 10 Items, wobei die Items der kleinen List jederzeit identisch sein sollen mit den Items 20-29 der großen Liste. In anderen Worten, die Beziehung

Code: Alles auswählen

kl[ind] is gr[20+ind]
soll jederzeit und fuer jedes 0<=ind<10 wahr sein.

Falls die Elemente vom gleichen Typ sind, kann man die Arrays von Numeric benutzen; da funktioniert es. Bei normalen Listen dagegen werden immer nur Kopien gemacht, die dann unabhängig voneinander behandelt werden.

Hat jemand eine Idee? Vielen Dank!
Zuletzt geändert von Goswin am Mittwoch 7. Mai 2008, 13:05, insgesamt 1-mal geändert.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

wenn die Items in der Liste mutable sind, dann funktioniert es:

Code: Alles auswählen

gl = [[i] for i in range(100)]
kl = gl[20:30]
kl[0] is gl[20] # true
kl[0][0] = 5
kl[0] is gl[20] # true
Bei immutables macht er dann eine Kopie:

Code: Alles auswählen

gl = [i for i in range(100)]
kl = gl[20:30]
kl[0] is gl[20] # true
kl[0] = 5
kl[0] is gl[20] # false
Entweder, du kapselst deine Immutables in einem Mutable, oder du implementierst eine eigene Liste, die auf deine Objekte aufpasst (wobei die wohl auch nichts anderes machen wird als oben).

Gruß,
Manuel
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich würde da eine Liste implementieren (die kleine Liste), die bei der Erstellung nur eine Referenz auf die große Liste bekommt und bei Zugriffen dann die Elemente as der großen Liste holt.

Ausbaufähige Minimalimplementation:

Code: Alles auswählen

>>> class sublist(list):
...   def __init__(self, ref):
...     self.ref = ref
...   def __getitem__(self, index):
...     if 0 <= index <= 9:
...         return self.ref[20 + index]
...     else:
...       raise IndexError('list index out of range')
... 
>>> gl = range(100)
>>> kl = sublist(gl)
>>> kl[0]
20
>>> kl[9]
29
>>> gl[22] = 7
>>> kl[2]
7
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@helduel:
Vielen Dank; deine Lösung sieht exotisch aus, aber sie funktioniert. Es genügt offenbar nicht, dass Listen mutabel sind, sondern die ListenELEMENTE müssen mutabel sein, was ich übersehen hatte.

@Leonidas:
Dein Beispiel funktioniert NICHT, wenn ich versuche

Code: Alles auswählen

kl[3] =123
einzugeben. Wie man beim Ausdrucken beobachten kann, ist die Teilliste immer eine LEERE Liste. Ich habe versucht, im Codeprogramm

Code: Alles auswählen

self.ref = ref[20:30]
zu schreiben, aber die kleine Liste bleibt leer.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Goswin hat geschrieben:@Leonidas:
Dein Beispiel funktioniert NICHT, wenn ich versuche

Code: Alles auswählen

kl[3] =123
einzugeben.
Natürlich nicht, ich habe ja "ausbaufähig" geschrieben. Das bedeutet, das erwartet wird, dass du es ausbaust. Aber gut, __setitem__ zu implementieren ist auch nicht schwer :)

``self.ref`` ist übrigens eine Referenz auf die liste, keine Kopie. Das ist auch so beabsichtigt, sonst würde das ja nicht bidirektional gehen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@Leonidas: Alles klar und ebenfalls vielen Dank. Jetzt funktioniert es auch bei mir. :D
Antworten