Einfache Python-Code über Doppelschleife

Ich habe den folgenden Python-Code auf Spyder IDE getestet. Denken, es würde 2d Array q als wachsende Zahl als 0..31 von q[0][0] bis q[3][7] ausgeben. Aber es gibt tatsächlich q als:

 [[24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31]]. 

Der Code:

 q=[[0]*8]*4 for i in range(4): for j in range(8): q[i][j] = 8*i+j print q 

Irgendeine Vorstellung davon, was hier passiert? Ich habe Schritt für Schritt debugge. Es zeigt die Updates jeder Zeile wird mit allen anderen Zeilen synchronisieren, ganz anders als meine Erfahrungen mit anderen Programmiersprachen.

3 Solutions collect form web for “Einfache Python-Code über Doppelschleife”

 q=[somelist]*4 

somelist eine Liste mit vier identischen Items, die Liste somelist . So z. B. q[0] und q[1] beziehen sich auf das gleiche Objekt.

Also, in der verschachtelten für Schleife q[i] referenziert die gleiche Liste unabhängig von dem Wert von i .

Reparieren:

 q = [[0]*8 for _ in range(4)] 

Das Listenverständnis bewertet [0]*8 4 verschiedene Zeiten, was zu 4 verschiedenen Listen führt.


Hier ist eine schnelle Demonstration dieser Fallstricke:

 In [14]: q=[[0]*8]*4 

Sie könnten denken, Sie aktualisieren nur das erste Element in der zweiten Zeile:

 In [15]: q[1][0] = 100 

Aber du endest am Ende das erste Element in jeder Zeile:

 In [16]: q Out[16]: [[100, 0, 0, 0, 0, 0, 0, 0], [100, 0, 0, 0, 0, 0, 0, 0], [100, 0, 0, 0, 0, 0, 0, 0], [100, 0, 0, 0, 0, 0, 0, 0]] 

Wie erklärt, wird das Problem aufgrund von * Operation auf Listen verursacht, die mehr Verweise auf dasselbe Objekt erzeugen. Was Sie tun sollten, ist zu verwenden:

 q=[] for i in range(4): q.append([]) for j in range(8): q[i].append(8*i+j) print q 

[8, 9, 10, 11, 12, 13, 14, 15] 22, 23], [24, 25, 26, 27, 28, 29, 30, 31]]

Wenn du so etwas wie l = [x]*8 machst, schaffst du eigentlich 8 Referenzen auf die gleiche list , nicht 8 Kopien.

Um wirklich 8 Exemplare zu bekommen, musst du l = [[x] for i in xrange(8)]

 >>> x=[1,2,3] >>> l=[x]*8 >>> l [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> l[0][0]=10 >>> l [[10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3]] >>> l = [ [x] for i in xrange(8)] >>> l [[[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]]] >>> l[0][0] = 1 >>> l [[1], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]]] 
Python ist die beste Programmiersprache der Welt.