68 Stimmen

2d Reihe von Nullen

In Python gibt es keinen Array-Typ, aber um ihn zu emulieren, können wir Listen verwenden. Ich möchte 2d Array-ähnliche Struktur mit Nullen gefüllt haben. Meine Frage ist: Was ist der Unterschied, wenn überhaupt, in diesen beiden Ausdrücken:

zeros = [[0 for i in xrange(M)] for j in xrange(M)]

y

zeros = [[0]*M]*N

Will zeros gleich sein? Welche ist in Bezug auf Geschwindigkeit und Lesbarkeit besser?

111voto

mgilson Punkte 280928

Sie sollten Folgendes verwenden numpy.zeros . Wenn das nicht möglich ist, brauchen Sie die erste Version. Wenn Sie in der zweiten Version einen Wert ändern, wird er auch an anderer Stelle in der Liste geändert - z. B.:

>>> a = [[0]*10]*10
>>> a
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> a[0][0] = 1
>>> a
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

Das liegt daran, dass Sie (wenn Sie den Ausdruck von innen nach außen lesen) eine Liste mit 10 Nullen erstellen. Anschließend erstellen Sie eine Liste mit 10 Verweisen auf diese ursprüngliche Liste mit 10 Nullen.


Beachten Sie das:

zeros = [ [0]*M for _ in range(N) ]  # Use xrange if you're still stuck in the python2.x dark ages :).

funktioniert ebenfalls und vermeidet das Verständnis der verschachtelten Liste. Wenn numpy nicht auf dem Tisch liegt, würde ich dieses Formular verwenden.

53voto

Zhe Hu Punkte 3445

Für Python 3 (kein xrange mehr), die bevorzugte Antwort

zeros = [ [0] * N for _ in range(M)]

für M x N Reihen von Nullen

25voto

Ivan Mushketyk Punkte 7459

Im zweiten Fall erstellen Sie eine Liste von Verweisen auf dieselbe Liste. Wenn Sie Code wie haben:

[lst] * N

wo die lst ein Verweis auf eine Liste ist, erhalten Sie die folgende Liste:

[lst, lst, lst, lst, ..., lst]

Da die Ergebnisliste jedoch Verweise auf dasselbe Objekt enthält, wird ein in einer Zeile geänderter Wert auch in allen anderen Zeilen geändert.

5voto

Crabigator360 Punkte 802

Die Antwort von Zhe Hu ist die sicherere und hätte die beste Antwort sein müssen. Denn wenn wir die akzeptierte Antwortmethode anwenden

a = [[0] * 2] * 2
a[0][0] = 1
print(a)

wird die Antwort geben

[[1,0],[1,0]]

Auch wenn Sie also nur den Wert der ersten Zeile und der ersten Spalte aktualisieren wollen, werden alle Werte in derselben Spalte aktualisiert. Jedoch

a = [[0] * 2 for _ in range(2)]
a[0][0] = 1
print(a)

gibt die richtige Antwort

[[1,0],[0,0]]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X