Seite 1 von 1

Eintrag in Liste wird ungewollt überschrieben durch Variable

Verfasst: Mittwoch 27. Februar 2008, 21:57
von enna
Hallo!

Ich habe folgendes Problem: Ich definiere eine Variable als Eintrag einer Liste und ändere dann diese Variable in einer Schleife. Danach ist aber die Liste ebenfalls geändert, und ich habe keine Ahnung, warum, und wie ich das verhindern kann. :?

Hier ist der Code; die Variable heisst "a_5", die ausversehen geänderte Liste "Zeilenperm":

Code: Alles auswählen

#INPUT
m=4

#erstelle Liste der Permutationen der Zahlen 0,...,m-1
list=[]
List=[] #wird Liste der Permutationen der Zahlen 0,...,m-1
for i in range(0,m):
    list.append([i])

from perm import perm
gen=perm(list)
try:
 	while 1:List.append(gen.next())
except StopIteration:
    pass

b_5=[-4,2,2,2,0,0,0,0]
b_6=[2,-4,2,2,0,0,0,0]
b_7=[2,2,-4,2,0,0,0,0]
b_8=[2,2,2,-4,0,0,0,0]
Zeilen=[b_5,b_6,b_7,b_8]
Zeilenperm=[] #wird Liste der Permutationen der Zeilen b_5,...,b_8
from perm import perm
gen=perm(Zeilen)
try:
 	while 1:Zeilenperm.append(gen.next())
except StopIteration:
    pass

for l in range(0,len(Zeilenperm)):
	for k in range(0,len(List)):
		a_5=Zeilenperm[l][0]
		if int(a_5[int(List[k][0][0])])==2:
			del a_5[int(List[k][0][0])]
			a_5.insert(int(List[k][0][0]),2.5)
		else:
			continue							    

print Zeilenperm
Die Funktion "perm", die das Programm aufruft, erstellt eine Liste mit Permutationen der Einträge einer anderen Liste; hier ebenfalls der Code:

Code: Alles auswählen

def perm(items, n=None):
    if n is None:
        n = len(items)
    for i in range(len(items)):
        v = items[i:i+1]
        if n == 1:
            yield v
        else:
            rest = items[:i] + items[i+1:]
            for p in perm(rest, n-1):
                yield v + p
Vielen Dank für die Hilfe!
Anne

Verfasst: Mittwoch 27. Februar 2008, 22:56
von Leonidas
Das liegt daran, dass Python mit Referenzen arbeitet. Wenn du eine Liste erstellst, enthält diese Referenzen auf die enthaltenen Objekte. Wenn du an einem Objekt rumschrauben willst, ohne dass es sich ändert, erstelle doch eine Kopie. Dafür gibt es das Modul ``copy``.

Dein ganzer Code zum generieren der Zahlen von 0 bis m-1 kann so abgekürzt werden: ``range(0, m)``. Das Ergebnis an ``list`` binden ist eine sehr schlechte Idee, da ``list()`` eine Builtin-Funktion ist, die du sicherlich gut brauchen könntest.

Auch der Code mit dem ``StopIteration`` ist seltsam:

Code: Alles auswählen

for element in perm(list_):
    List_.append(element)
Tut das gleiche, sieht aber doch klarer aus. Nur musst du den Variablen sinnvolle Namen geben.