398 Stimmen

Wie initialisiert man ein zweidimensionales Array in Python?

Ich fange mit Python an und ich versuche, eine zweidimensionale Liste zu verwenden, die ich anfangs an jeder Stelle mit derselben Variablen fülle. Ich bin auf Folgendes gekommen:

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 liefert das gewünschte Ergebnis, fühlt sich aber wie ein Workaround an. Gibt es einen einfacheren/kürzeren/eleganteren Weg, dies zu tun?

621voto

Jason CHAN Punkte 4777

Verwenden Sie nicht [[v]*n]*n, das ist eine Falle!

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

aber

    t = [ [0]*3 for i in range(3)]

funktioniert super.

418voto

Mike Graham Punkte 68846

Ein Muster, das oft in Python auftauchte, war

bar = []
for item in some_iterable:
    bar.append(SOME EXPRESSION)

was dazu beitrug, die Einführung von Listenverständnissen zu motivieren, die diesen Ausschnitt in

bar = [SOME_EXPRESSION for item in some_iterable]

umwandeln, was kürzer und manchmal klarer ist. Normalerweise gewöhnt man sich daran, diese zu erkennen und oft Schleifen durch Verständnisse zu ersetzen.

Ihr Code folgt diesem Muster zweimal

twod_list = []                                       \                      
for i in range (0, 10):                               \
    new = []                  \ kann ersetzt werden    } das auch
    for j in range (0, 10):    } durch eine Liste     /
        new.append(foo)       / Verstehen          /
    twod_list.append(new)                           /

275voto

Adam Rosenfield Punkte 373807

Sie können eine Listenabstraktion verwenden:

x = [[foo for i in range(10)] for j in range(10)]
# x ist jetzt ein 10x10 Array von 'foo' (das von i und j abhängen kann, wenn Sie möchten)

154voto

John La Rooy Punkte 278961

Dieser Weg ist schneller als die verschachtelten Listenverständnisse

[x[:] for x in [[foo] * 10] * 10]    # für unveränderliches foo!

Hier sind einige Python3-Zeiten für kleine und große Listen

$python3 -m timeit '[x[:] for x in [[1] * 10] * 10]'
1000000 Schleifen, bester von 3: 1,55 usec pro Schleife

$ python3 -m timeit '[[1 for i in range(10)] for j in range(10)]'
100000 Schleifen, bester von 3: 6,44 usec pro Schleife

$ python3 -m timeit '[x[:] for x in [[1] * 1000] * 1000]'
100 Schleifen, bester von 3: 5,5 msec pro Schleife

$ python3 -m timeit '[[1 for i in range(1000)] for j in range(1000)]'
10 Schleifen, bester von 3: 27 msec pro Schleife

Erklärung:

[[foo]*10]*10 erstellt eine Liste des gleichen Objekts, das 10 Mal wiederholt wird. Du kannst das nicht einfach so verwenden, weil das Ändern eines Elements dieses Element in jeder Zeile ändert!

x[:] entspricht list(X), ist aber etwas effizienter, da es den Namensaufruf umgeht. So oder so erstellt es eine oberflächliche Kopie jeder Zeile, sodass jetzt alle Elemente unabhängig sind.

Alle Elemente sind jedoch das gleiche foo Objekt, daher, wenn foo veränderlich ist, kannst du dieses Schema nicht verwenden., musst du

import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]

oder unter der Annahme einer Klasse (oder Funktion) Foo, die foos zurückgibt

[[Foo() for x in range(10)] for y in range(10)]

78voto

Vipul Punkte 3900

Um ein zweidimensionales Array in Python zu initialisieren:

a = [[0 for x in range(Spalten)] for y in range(Zeilen)]

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