Warum beeinflusst foo.append (bar) alle Elemente in einer Liste von Listen? [Duplikat]

7

Ich erstelle eine Liste von Listen und möchte Objekte an die einzelnen Listen anhängen, aber wenn ich versuche, an eine der Listen anzuhängen ( a[0].append(2) ), wird das Element zu allen Listen hinzugefügt.

%Vor%

Gibt: [[1, 2, 3], [1, 2, 3]]

Ich würde erwarten: [[1, 2], [1, 3]]

Ich ändere die Art, wie ich die erste Liste von Listen konstruiere, indem ich b zu einem Float anstelle einer Liste mache und die Klammern in .append() setze, gibt mir die gewünschte Ausgabe:

%Vor%

Gibt: [[1, 2], [1, 3]]

Aber warum? Es ist nicht intuitiv, dass das Ergebnis anders sein sollte. Ich weiß, dass dies damit zu tun hat, dass mehrere Verweise auf dasselbe sind Liste , aber ich sehe nicht, wo das passiert.

    
litturt 15.06.2011, 15:31
quelle

3 Antworten

20

Dies liegt daran, dass die Liste Verweise auf Objekte enthält. Ihre Liste enthält nicht [[1 2 3] [1 2 3]] , sondern [<reference to b> <reference to b>] .

Wenn Sie das Objekt ändern (indem Sie etwas an b anhängen), ändern Sie das Objekt selbst, nicht die Liste, die das Objekt enthält.

Um den gewünschten Effekt zu erhalten, muss Ihre Liste a Kopien von b enthalten und nicht Referenzen auf b . Um eine Liste zu kopieren, können Sie den Bereich [:] verwenden. Zum Beispiel:

%Vor%     
Bryan Oakley 15.06.2011, 15:33
quelle
1

Der Schlüssel ist dieser Teil:

%Vor%

Sie hängen dieselbe Liste zweimal an, daher sind sowohl a[0] als auch a[1] Verweise auf dieselbe Liste.

In Ihrem zweiten Beispiel erstellen Sie jedes Mal neue Listen, wenn Sie append wie a.append([b]) aufrufen, also sind sie separate Objekte, die mit demselben Gleitkommawert initialisiert werden.

    
Gavin H 15.06.2011 15:34
quelle
1

Um eine flache Kopie einer Liste zu erstellen, ist das Idiom

%Vor%

was, wenn es verdoppelt wird, dazu führt, dass zwei neue Kopien der Liste b haben, die Ihnen den von Ihnen gemeldeten Aliasing-Fehler nicht geben.

    
msw 15.06.2011 15:37
quelle

Tags und Links