Tupel mit list-Elementen

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: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Es heißt zwar immer, dass Tupel ganz _unveränderbar_ sind (weshalb ich im folgenden Codestück eine Fehlermeldung erwartet hatte), aber siehe, es funktioniert trotzdem:

Code: Alles auswählen

a = [1,2]
b = [3,4]
tt = [a,b]  #Tippfehler; mit tt = (a,b) funkts aber immer noch!
print(tt)
tt[0][0] = 0
print(tt)
Was passiert hinter den Kulissen, wenn ich ein einzelnes Element der "Matrix" tt ändere? Wird das gesamte Tupelobjekt tt neu gebaut und das alte verworfen, oder wird nur das entsprechende Listenelement ersetzt?
Zuletzt geändert von Goswin am Montag 19. April 2010, 12:49, insgesamt 1-mal geändert.
Python nervt. (Nicht immer, und natürlich nur mich, niemals andere)
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Code: Alles auswählen

In [1]: a = [1, 2]

In [2]: type(a)
Out[2]: <type 'list'>

In [3]: b = [3, 4]

In [4]: type(b)
Out[4]: <type 'list'>

In [5]: tt = [a, b]

In [6]: type(tt)
Out[6]: <type 'list'>

In [7]: a = (1, 2)

In [8]: type(a)
Out[8]: <type 'tuple'>
BlackJack

@Goswin: In Deinem Quelltext kommt gar kein Tupel vor, sondern nur Listen.

Und es wird nur die Liste verändert, denn darauf bezieht sich die Zuweisung letztendlich nur. Hinter den Kulissen passiert folgendes:

Code: Alles auswählen

x[i][j] = v
# ->
x.__getitem__(i).__setitem__(j, v)
Das *Tupel* wird in Deinem Fall (ich nehme mal an `tt` sollte eigentlich eins sein) nicht verändert. Von dem wird nur das Listenobjekt erfragt.
Benutzeravatar
Goswin
User
Beiträge: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Ops, ich hatte oben mich verschrieben... Ich meinte natürlich was folgt:

Es heißt zwar immer, dass Tupel ganz _unveränderbar_ sind (weshalb ich im folgenden Codestück eine Fehlermeldung erwartet hatte), aber siehe, es funktioniert trotzdem:

Code: Alles auswählen

a = [1,2]
b = [3,4]
tt = tuple((a,b))
print(tt)
tt[0][0] = 0
print(tt)
Was passiert hinter den Kulissen, wenn ich ein einzelnes Element der "Matrix" tt ändere? Wird das gesamte Tupelobjekt tt neu gebaut und das alte verworfen, oder wird nur das entsprechende Listenelement ersetzt?
Python nervt. (Nicht immer, und natürlich nur mich, niemals andere)
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Das Tupel tt enthält ja nur Referenzen auf Listenobjekte. Wenn du eine der Listen Modifizierst, änderst du ja nicht die Referenz, sondern die Liste. Und das geht.
BlackJack

@Goswin: Jetzt wolltest Du wohl *ganz* gründlich sein. :-) Du gibst der `tuple()`-Funktion bereits ein Tupel. Dadurch wird es nicht doppelt so "tupelig" ;-) Es würde sogar ``tt = a, b`` genügen. Nur eckige Klammern darf man halt nicht setzen.
Benutzeravatar
Goswin
User
Beiträge: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@.robert:
Wenn ich eine groooße Matrix habe, ist die Änderung eines Einzelelements dann wohl schneller bei einem _Tupel_ voller Listen als bei einer _Liste_ voller Listen?
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

"premature optimization is the root of all evil"

Triff die Wahl ob List oder Tupel danach, was für Funktionen du brauchst, nicht was schneller ist.
Aber Tupel sind vor allem effizienter mit dem Speicherplatz, da Listen "auf Verdacht" Speicher vor reservieren.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Goswin hat geschrieben:@.robert:
Wenn ich eine groooße Matrix habe, ist die Änderung eines Einzelelements dann wohl schneller bei einem _Tupel_ voller Listen als bei einer _Liste_ voller Listen?
Willst du numpy verwenden? Aber was verstehst du unter groß?
[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]
Benutzeravatar
Goswin
User
Beiträge: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:Es würde sogar ``tt = a, b`` genügen. Nur eckige Klammern darf man halt nicht setzen.
In der Tat, wenn wir das "nur" nicht zu wörtlich nehmen. Ich falle immer wieder auf die Schreibweise "tt = tuple(a,b)" herein, was ja paradoxerweise auch falsch ist... :P
Benutzeravatar
Goswin
User
Beiträge: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

.robert hat geschrieben:"premature optimization is the root of all evil"
"It is never too early to think about performance",
Rebecca Parsons in "97_Things Every Software Architect Should Know", O'Reilly, 2009.
Tja, so schnell veralten die Weisheiten :wink: !

Aber meine Matrix hat unveränderliche Dimensionen, da werden die Tupel wohl etwas speichersparend sein.
Vielen Dank für eure Hinweise.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Goswin hat geschrieben:
.robert hat geschrieben:"premature optimization is the root of all evil"
"It is never too early to think about performance",
Rebecca Parsons in "97_Things Every Software Architect Should Know", O'Reilly, 2009.
Tja, so schnell veralten die Weisheiten :wink: !
Naja im 2. Quote geht es wohl v.a. um Designentscheidungen (-> Architect), die sind nur schlecht wieder gerade zu biegen. Und um so eine handelt es sich hier IMO durchaus, mit Tupeln und Listen kann und muss man anders arbeiten.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

@Goswin: Ich frag nochmal, wie groß ist denn deine Matrix?
[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]
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Goswin hat geschrieben:@.robert:
Wenn ich eine groooße Matrix habe, ist die Änderung eines Einzelelements dann wohl schneller bei einem _Tupel_ voller Listen als bei einer _Liste_ voller Listen?
Nein, das wird keinen Unterschied machen.

Aber vermutlich wills du wirklich ein numpy-Array verwenden. Das ist schneller und verbraucht vor allem massiv weniger Speicher. Einem Numpy-Array liegt ein C-Array zugrunde, d.h. es braucht nur so viel Speicher wie die Daten auch brauchen. Deine Konstruktion braucht erstmal den Speicher für die Zeiger, die Listenobjekte und die Daten(die auch Python-Objekte sind und Speicher fressen). Tippe mal drauf, dass das mindestens einen Faktor 4 ausmachen wird. Alternativ kannst du auch ein array.array nehmen.
Benutzeravatar
Goswin
User
Beiträge: 366
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

jbs hat geschrieben:@Goswin: Ich frag nochmal, wie groß ist denn deine Matrix?
Diese Frage ist falsch gestellt (je größer meine Matrix sein darf, desto mehr Events kann ich in Realzeit analysieren).

@Radii: Ja, vermutlich sollte ich numpy benutzen.
Antworten