Ich beginne mit Python und versuche, eine zweidimensionale Liste zu verwenden, die ich zunächst an jeder Stelle mit derselben Variablen fülle. Ich habe mir das ausgedacht:
def initialize_twodlist(foo):
twod_list = []
new = []
for i in range (0, 10):
for j in range (0, 10):
new.append(foo)
twod_list.append(new)
new = []
Es gibt das gewünschte Ergebnis, fühlt sich aber wie eine Problemumgehung an. Gibt es eine einfachere / kürzere / elegantere Möglichkeit, dies zu tun?
python
multidimensional-array
thepandaatemyface
quelle
quelle
Antworten:
Ein Muster, das in Python häufig vorkam, war
Dies hat dazu beigetragen, die Einführung von Listenverständnissen zu motivieren, die dieses Snippet in konvertieren
Das ist kürzer und manchmal klarer. Normalerweise gewöhnt man sich an, diese zu erkennen und Schleifen oft durch Verständnis zu ersetzen.
Ihr Code folgt diesem Muster zweimal
quelle
[foo] * 10
ist eine Liste mit genau dem gleichenfoo
10-fachen, was wichtig sein kann oder nicht.[foo] * 10
: Das bedeutet , dass dies nicht funktionieren würde , wenn Sie ein Array mit Zufallszahlen sind Füllung (auswertet[random.randint(1,2)] * 10
zu[1] * 10
oder[2] * 10
was bedeutet , dass Sie ein Array aller 1s oder 2s erhalten, anstelle einer zufälligen Anordnung.Sie können ein Listenverständnis verwenden :
quelle
i
für Zeilen undj
für die Spalten, ich denke , es zu tauschen sollte besser seini
undj
zum besseren Verständnis in der Syntax und die Reichweite zu 2 verschiedenen Nummern ändern.Dieser Weg ist schneller als das Verständnis verschachtelter Listen
Hier sind einige Python3-Timings für kleine und große Listen
Erläuterung:
[[foo]*10]*10
Erstellt eine Liste desselben Objekts, die zehnmal wiederholt wird. Sie können dies nicht einfach verwenden, da durch Ändern eines Elements dasselbe Element in jeder Zeile geändert wird!x[:]
ist äquivalent zulist(X)
, ist aber etwas effizienter, da die Namenssuche vermieden wird. In beiden Fällen wird eine flache Kopie jeder Zeile erstellt, sodass jetzt alle Elemente unabhängig sind.Alle Elemente sind jedoch dasselbe
foo
Objekt. Wennfoo
es also veränderbar ist , können Sie dieses Schema nicht verwenden. Sie müssten es verwendenoder eine Klasse (oder Funktion) annehmen
Foo
, diefoo
s zurückgibtquelle
copy.deepcopy
. Sie benötigen einen für Ihre Daten spezifischen Plan, wenn Sie ein beliebiges veränderbares Objekt haben.x
undy
. Sollte es nicht sein[[copy.deepcopy(foo) for y in range(10)] for x in range(10)]
[foo]*10
keine 10 verschiedenen Objekte - aber es ist leicht, den Unterschied zu übersehen, wenn foo unveränderlich ist, wie einint
oderstr
.Nicht benutzen
[[v]*n]*n
, es ist eine Falle!aber
funktioniert super.
quelle
*
liegt daran, dassaddress
das Objekt (Liste) kopiert wird .[[0] * col for _ in range(row)]
.So initialisieren Sie ein zweidimensionales Array in Python:
quelle
a = [[0 for x in range(columns)] for y in range(rows)]
.quelle
[[0] * col] * row
nicht das tun, was Sie wollen, ist, dass Python beim Initialisieren einer 2D-Liste auf diese Weise nicht für jede Zeile unterschiedliche Kopien erstellt. Stattdessen wird die äußere Liste mit Zeigern auf dieselbe Kopie von initiiert[0]*col
. Jede Änderung, die Sie an einer der Zeilen vornehmen, wird dann in den verbleibenden Zeilen wiedergegeben, da alle tatsächlich auf dieselben Daten im Speicher verweisen.Wenn Sie mehrdimensionale Arrays möchten, möchten Sie normalerweise keine Liste von Listen, sondern ein numpy-Array oder möglicherweise ein Diktat.
Zum Beispiel würden Sie mit numpy so etwas tun
quelle
numpy
es großartig ist, denke ich, dass es für einen Anfänger ein bisschen übertrieben sein könnte.numpy
. +1Sie können genau das tun:
Beispielsweise:
Dies hat jedoch einen unerwünschten Nebeneffekt:
quelle
denn n ist die Anzahl der Zeilen und m ist die Anzahl der Spalten und foo ist der Wert.
quelle
Wenn es sich um ein dünn besiedeltes Array handelt, ist es möglicherweise besser, ein Wörterbuch mit einem Tupel zu verwenden:
quelle
Für jedes Element wird ein neues
[0]*10
erstellt.quelle
Falscher Ansatz: [[Keine * m] * n]
Bei diesem Ansatz erlaubt Python nicht, einen anderen Adressraum für die äußeren Spalten zu erstellen, und führt zu verschiedenen Fehlverhalten als erwartet.
Richtiger Ansatz, aber mit Ausnahme:
Es ist ein guter Ansatz, aber es gibt eine Ausnahme, wenn Sie den Standardwert auf setzen
None
Stellen Sie Ihren Standardwert mit diesem Ansatz richtig ein.
Absolut richtig:
Folgen Sie der Antwort des Mikrofons auf Doppelschleife .
quelle
quelle
So initialisieren Sie ein zweidimensionales Array:
arr = [[]*m for i in range(n)]
tatsächlich,
arr = [[]*m]*n
wird ein 2D-Array erstellt, in dem alle n Arrays auf dasselbe Array verweisen, sodass jede Wertänderung in einem Element in allen n Listen berücksichtigt wirdWeitere Erklärungen finden Sie unter: https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
quelle
Verwenden Sie den einfachsten Gedanken, um dies zu erstellen.
und füge die Größe hinzu:
oder wenn wir zuerst die Größe deklarieren wollen. wir verwenden nur:
quelle
Wie @Arnab und @Mike betonten, ist ein Array keine Liste. Es gibt nur wenige Unterschiede: 1) Arrays haben während der Initialisierung eine feste Größe. 2) Arrays unterstützen normalerweise weniger Operationen als eine Liste.
In den meisten Fällen vielleicht ein Overkill, aber hier ist eine grundlegende 2D-Array-Implementierung, die die Hardware-Array-Implementierung mithilfe von Python-C-Typen (C-Bibliotheken) nutzt.
quelle
Das Wichtige, was ich verstanden habe, ist: Beim Initialisieren eines Arrays (in einer beliebigen Dimension) sollten wir allen Positionen des Arrays einen Standardwert geben. Dann ist nur die Initialisierung abgeschlossen. Danach können wir an jeder Position des Arrays neue Werte ändern oder empfangen. Der folgende Code hat bei mir perfekt funktioniert
quelle
Wenn Sie numpy verwenden , können Sie problemlos 2D-Arrays erstellen:
x
quelle
Das Obige gibt Ihnen ein 5x5 2D-Array
Es verwendet das Verständnis verschachtelter Listen. Aufschlüsselung wie folgt:
[x] * col -> endgültiger Ausdruck, der
für x in -> x ausgewertet wird, ist der vom Iterator bereitgestellte Wert
[b für b im Bereich (Zeile)] -> Iterator.
[b für b im Bereich (Zeile)]] wird dies zu [0,1,2,3,4] ausgewertet, da Zeile = 5 ist,
so dass es jetzt vereinfacht wird
Dies ergibt [[0] * 5 für x in [0,1,2,3,4]] -> mit x = 0 1. Iteration
[[1] * 5 für x in [0,1,2, 3,4]] -> mit x = 1 2. Iteration
[[2] * 5 für x in [0,1,2,3,4]] -> mit x = 2 3. Iteration
[[3] * 5 für x in [0,1,2,3,4]] -> mit x = 3 4. Iteration
[[4] * 5 für x in [0,1,2,3,4]] -> mit x = 4 5. Iteration
quelle
Dies ist das Beste, was ich gefunden habe, um neue Programmierer zu unterrichten und ohne zusätzliche Bibliotheken zu verwenden. Ich hätte gerne etwas Besseres.
quelle
Hier ist ein einfacher Weg:
Verwenden Sie zum Initialisieren aller Zellen mit einem beliebigen 'x'-Wert:
quelle
Oft verwende ich diesen Ansatz zum Initialisieren eines zweidimensionalen Arrays
n=[[int(x) for x in input().split()] for i in range(int(input())]
quelle
Das allgemeine Muster zum Hinzufügen von Dimensionen könnte aus dieser Reihe gezogen werden:
quelle
Sie können dies versuchen [[0] * 10] * 10. Dies gibt das 2d-Array mit 10 Zeilen und 10 Spalten mit dem Wert 0 für jede Zelle zurück.
quelle
a = [[0]*10]*10
und dann sehena[0][0] = 1
Sie das erste Element in jeder Zeile jetzt gleich 1lst = [[0] * m für i im Bereich (n)]
Initialisieren Sie alle Matrix n = Zeilen und m = Spalten
quelle
Eine andere Möglichkeit besteht darin, ein Wörterbuch zu verwenden, um ein zweidimensionales Array aufzunehmen.
Dies kann nur beliebige 1D-, 2D-Werte enthalten. Um dies mit
0
einem anderen int-Wert zu initialisieren , verwenden Sie Sammlungen .quelle
Code:
initial_val
muss unveränderlich sein.quelle
quelle