So definieren Sie ein zweidimensionales Array in Python


723

Ich möchte ein zweidimensionales Array ohne eine initialisierte Länge wie folgt definieren:

Matrix = [][]

aber es funktioniert nicht...

Ich habe den folgenden Code ausprobiert, aber er ist auch falsch:

Matrix = [5][5]

Error:

Traceback ...

IndexError: list index out of range

Was ist mein Fehler?


14
Man definiert keine Arrays oder andere Dinge. Sie können jedoch mehrdimensionale Sequenzen erstellen, wie die Antworten hier zeigen. Denken Sie daran, dass Python- Variablen nicht typisiert sind, die Werte jedoch stark typisiert sind.
SingleNegationElimination

1
Ich bin verwirrt. Aus anderen Sprachen: Es ist ein Unterschied zwischen einem 1D-Array mit 1D-Arrays und einem 2D-Array. Und AFAIK gibt es keine Möglichkeit, ein mehrdimensionales Array (oder eine Liste) in Python zu haben. Sollte hier gesagt werden ...
Dirk Reichel

Antworten:


1008

Sie versuchen technisch, ein nicht initialisiertes Array zu indizieren. Sie müssen zuerst die äußere Liste mit Listen initialisieren, bevor Sie Elemente hinzufügen. Python nennt dies "Listenverständnis".

# Creates a list containing 5 lists, each of 8 items, all set to 0
w, h = 8, 5;
Matrix = [[0 for x in range(w)] for y in range(h)] 

Sie können der Liste jetzt Elemente hinzufügen:

Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range... 
Matrix[0][6] = 3 # valid

Beachten Sie, dass die Matrix "y" -Adresse major ist, mit anderen Worten, der "y-Index" steht vor dem "x-Index".

print Matrix[0][0] # prints 1
x, y = 0, 6 
print Matrix[x][y] # prints 3; be careful with indexing! 

Obwohl Sie sie nach Ihren Wünschen benennen können, sehe ich das so, um Verwirrung zu vermeiden, die bei der Indizierung auftreten kann, wenn Sie "x" sowohl für die innere als auch für die äußere Liste verwenden und eine nicht quadratische Matrix wünschen.


219
[[0 für x im Bereich (cols_count)] für x im Bereich (rows_count)]
Songhir

3
Seltsame Bearbeitung von ademar111190. In Python 3 gibt es keinen xrange, aber wenn Sie Python 2 verwenden müssen, ist xrange die richtige Funktion, wenn Sie keine unnötigen Objekte erstellen möchten.
Dave

4
@ Dave Wenn Sie es nicht mit Nullen gefüllt brauchen, können Sie rangedie internen Listen direkt erstellen:[range(5) for x in range(5)]
Alanjds

2
@alanjds - das stimmt, aber Sie erstellen in Python 2 möglicherweise noch viele unnötige Objektreferenzen für die äußere Iteration (versuchen Sie dies mit einem SEHR großen Bereich). Außerdem ist die Initialisierung auf einen bestimmten Wert fast immer das, was Sie möchten - und dies ist meistens 0. Der Bereich ergibt eine iterierbare Sammlung - xrange gibt einen Generator zurück. Mein Punkt war, dass Ademar etwas "korrigierte", das tatsächlich allgemeiner korrekt und effizienter war als seine Korrektur.
Dave

10
@ 6packkid das [0] * wTeil ist nett, wird aber [[0] * w] * h]unerwartetes Verhalten erzeugen. Versuchen Sie mat = [[0] * 3] * 3; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 10, 0], [0, 10, 0]])und mat = [[0] * 3 for i in range(3)]; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 0, 0], [0, 0, 0]]).
senderle

407

Wenn Sie wirklich eine Matrix wollen, ist es möglicherweise besser, sie zu verwenden numpy. Matrixoperationen verwenden numpymeistens einen Array-Typ mit zwei Dimensionen. Es gibt viele Möglichkeiten, ein neues Array zu erstellen. Eine der nützlichsten zerosFunktionen ist die Funktion, die einen Formparameter verwendet und ein Array der angegebenen Form mit den auf Null initialisierten Werten zurückgibt:

>>> import numpy
>>> numpy.zeros((5, 5))
array([[ 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.]])

Hier sind einige andere Möglichkeiten, um 2D-Arrays und Matrizen zu erstellen (wobei die Ausgabe aus Gründen der Kompaktheit entfernt wurde):

numpy.arange(25).reshape((5, 5))         # create a 1-d range and reshape
numpy.array(range(25)).reshape((5, 5))   # pass a Python range and reshape
numpy.array([5] * 25).reshape((5, 5))    # pass a Python list and reshape
numpy.empty((5, 5))                      # allocate, but don't initialize
numpy.ones((5, 5))                       # initialize with ones

numpystellt auch einen matrixTyp zur Verfügung, wird jedoch für keine Verwendung mehr empfohlen und kann in Zukunft entfernt werden.numpy


79
Wann immer Sie Matrizen möchten, möchten Sie numpy verwenden. Diese Antwort sollte zuerst sein.
Pat B

2
Die Tatsache, dass die Frage das englische Wort "Matrix" verwendet, bedeutet nicht, dass sie es darstellen sollten np.matrix. Die richtige Art, eine Matrix in Numpy darzustellen, ist mit einem array.
user2357112 unterstützt Monica

@ user2357112, Und wie Sie sehen können, geben die meisten der oben aufgeführten Beispiele arrays anstelle von Matrizen aus. Obwohl dies nicht immer empfohlen wird, gibt es legitime Gründe für die Verwendung matrix- Kontextfragen.
senderle

1
@senderle, können Sie die Gründe für die Verwendung erweitern matrix? Seit @Einführung des Operators scheint es einen Grund weniger zu geben, seit dieser Beitrag geschrieben wurde.
Jpp

1
@jpp, wie der Beitrag bereits sagte, könnten Leute, die von matlab kommen, es nützlich finden. Aber die numpyDokumente zeigen jetzt an, dass die Klasse in Zukunft möglicherweise veraltet und entfernt wird, also habe ich sie aus der Antwort herausgenommen.
senderle

337

Hier ist eine kürzere Notation zum Initialisieren einer Liste von Listen:

matrix = [[0]*5 for i in range(5)]

Leider 5*[5*[0]]funktioniert es nicht wirklich, dies auf so etwas wie zu kürzen, da Sie am Ende 5 Kopien derselben Liste haben. Wenn Sie also eine davon ändern, ändern sich alle, zum Beispiel:

>>> matrix = 5*[5*[0]]
>>> matrix
[[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]]
>>> matrix[4][4] = 2
>>> matrix
[[0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2]]

4
Können Sie die Logik hinter dem "Verkürzungs" -Fehler erklären? Warum gibt Python in diesem Fall Kopien derselben Liste und im Fall von ein Array verschiedener Zellen aus [0]*5?
Mike622867

12
Die obigen Kommentare sind nicht genau richtig: [0] * 5 erstellt immer noch eine Sequenz mit dem 5-fachen Verweis auf dasselbe Objekt, das die Zahl 0 darstellt. Sie werden dies jedoch nie bemerken, da 0 unveränderlich ist (ich würde sagen, 0 verhält sich wie ein Wert - oder Sie könnten es als primitiven Datentyp betrachten - weil es unveränderlich ist, so dass Sie nie Probleme mit Verweisen auf dasselbe Objekt bekommen, anstatt Kopien zu haben.)
dreua

4
pythonischer: [[0]*5 for _ in range(5)]mit anonymem Schleifenzähler, den Sie nicht verwenden
Jean-François Fabre

Schön, dass Sie im zweiten Beispiel auf das Problem der flachen Kopie hinweisen.
Whatacold

danke @dreua, ich war wirklich verwirrt, wie gut das [0]*5funktioniert. Jetzt verstehe ich, warum [{0}]*8das auch eine schlechte Idee wäre.
Kuku

110

Wenn Sie eine leere Matrix erstellen möchten, lautet die korrekte Syntax

matrix = [[]]

Und wenn Sie eine Matrix der Größe 5 erzeugen möchten, die mit 0 gefüllt ist,

matrix = [[0 for i in xrange(5)] for i in xrange(5)]

@KorayTugay Da die Matrix mithilfe von Python-Listen (den Zeilen) dargestellt wird, die in einer anderen Liste (den Spalten) verschachtelt sind.
Elig

2
Für Python-3 verwenden Sie stattdessen die Bereichsfunktion xrange func
Rakesh Chaudhari

76

Wenn Sie nur einen zweidimensionalen Container für einige Elemente benötigen, können Sie stattdessen bequem ein Wörterbuch verwenden:

Matrix = {}

Dann können Sie tun:

Matrix[1,2] = 15
print Matrix[1,2]

Dies funktioniert, weil 1,2es sich um ein Tupel handelt und Sie es als Schlüssel zum Indizieren des Wörterbuchs verwenden. Das Ergebnis ähnelt einer dummen, spärlichen Matrix.

Wie von osa und Josap Valls angegeben, können Sie auch verwenden, Matrix = collections.defaultdict(lambda:0)damit die fehlenden Elemente den Standardwert von haben 0.

Vatsal weist ferner darauf hin, dass diese Methode für große Matrizen wahrscheinlich nicht sehr effizient ist und nur in nicht leistungskritischen Teilen des Codes verwendet werden sollte.


2
Dann können Sie auch nicht import collections; Matrix = collections.defaultdict(float)initialisierte Elemente durch Nullen ersetzen.
osa

2
Würde der Zugriff auf ein Diktat für Tupel (1,2) als Schlüssel nicht die Worst-Case-Komplexität von O (n) haben. Wie intern würde es die Tupel hashen. Während die Verwendung eines 2D-Arrays eine zeitliche Komplexität von O (1) für den Zugriff auf den Index [1,2] ergeben würde. Daher sollte es keine gute Wahl sein, dikt dafür zu verwenden.
Vatsal

@Vatsal wiki.python.org/moin/TimeComplexity sagt, dass der durchschnittliche Fall O (1) ist, aber Sie haben Recht mit dem schlimmsten Fall. Wie auch immer, wenn Sie nicht über VIELE EINZELTEILE sprechen, würde Sie dieser Unterschied nicht interessieren. Tatsächlich würde ich mir mehr Sorgen um den Speicher als um die Zugriffszeit machen.
Enobayram

Außerdem versuchen wir immer, die Verwendung von Diktaten zu vermeiden, bis die Gesamtkomplexität des Algorithmus gleich oder größer als O (n ^ 2) ist. Als 'n' mal würden O (n) Zugriffe eine O (n ^ 2) Komplexität ergeben.
Vatsal

@ Enobayram, Entschuldigung, aber ich stimme nicht zu. Eine asymptotische Analyse ergibt immer O (n ^ 2), wenn ein O (n) -Zugriff im schlimmsten Fall 'n' Mal durchgeführt wird. Wobei als amortisierte Analyse eine geringere Grenze ergeben kann. Und es gibt einen großen Unterschied zwischen amortisiertem und durchschnittlichem Fall ... bitte beziehen Sie sich, bevor Sie irgendwelche Annahmen und vagen Kommentare machen
Vatsal

42

In Python erstellen Sie eine Liste von Listen. Sie müssen die Dimensionen nicht im Voraus deklarieren, können dies aber. Zum Beispiel:

matrix = []
matrix.append([])
matrix.append([])
matrix[0].append(2)
matrix[1].append(3)

Jetzt Matrix [0] [0] == 2 und Matrix [1] [0] == 3. Sie können auch die Syntax des Listenverständnisses verwenden. In diesem Beispiel wird es zweimal verwendet, um eine "zweidimensionale Liste" zu erstellen:

from itertools import count, takewhile
matrix = [[i for i in takewhile(lambda j: j < (k+1) * 10, count(k*10))] for k in range(10)]

6
extendDies wäre auch im ersten Fall hilfreich: Wenn Sie mit beginnen m = [[]], können Sie der inneren Liste hinzufügen (eine Zeile erweitern) mit m[0].extend([1,2])und der äußeren Liste hinzufügen (eine neue Zeile anhängen) m.append([3,4]), und diese Operationen würden Sie verlassen [[1, 2], [3, 4]].
Askewchan

22

Die akzeptierte Antwort ist gut und richtig, aber ich habe eine Weile gebraucht, um zu verstehen, dass ich damit auch ein vollständig leeres Array erstellen kann.

l =  [[] for _ in range(3)]

führt zu

[[], [], []]

22

Sie sollten eine Liste mit Listen erstellen. Der beste Weg ist, verschachtelte Verständnisse zu verwenden:

>>> matrix = [[0 for i in range(5)] for j in range(5)]
>>> pprint.pprint(matrix)
[[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]]

In Ihrem [5][5]Beispiel erstellen Sie eine Liste mit einer Ganzzahl "5" und versuchen, auf das fünfte Element zuzugreifen. Dadurch wird natürlich ein IndexError ausgelöst, da kein fünftes Element vorhanden ist:

>>> l = [5]
>>> l[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Tatsächlich lautet die Reihenfolge für row_index ('i') und column_index ('j') wie folgt: '>>> matrix = [[0 für column_index in range (5)] für row_index in range (5)]'
Aniruddha Kalburgi

22
rows = int(input())
cols = int(input())

matrix = []
for i in range(rows):
  row = []
  for j in range(cols):
    row.append(0)
  matrix.append(row)

print(matrix)

Warum so ein langer Code, den PythonSie auch fragen?

Vor langer Zeit, als ich mit Python nicht vertraut war, sah ich die einzeiligen Antworten zum Schreiben einer 2D-Matrix und sagte mir, dass ich in Python keine 2-D-Matrix mehr verwenden werde. (Diese einzelnen Zeilen waren ziemlich beängstigend und gaben mir keine Informationen darüber, was Python tat. Beachten Sie auch, dass mir diese Abkürzungen nicht bekannt sind.)

Hier ist der Code für Anfänger mit C-, CPP- und Java-Hintergrund

Hinweis für Python-Liebhaber und Experten: Bitte stimmen Sie nicht ab, nur weil ich einen detaillierten Code geschrieben habe.


13

Ein Umschreiben zum einfachen Lesen:

# 2D array/ matrix

# 5 rows, 5 cols
rows_count = 5
cols_count = 5

# create
#     creation looks reverse
#     create an array of "cols_count" cols, for each of the "rows_count" rows
#        all elements are initialized to 0
two_d_array = [[0 for j in range(cols_count)] for i in range(rows_count)]

# index is from 0 to 4
#     for both rows & cols
#     since 5 rows, 5 cols

# use
two_d_array[0][0] = 1
print two_d_array[0][0]  # prints 1   # 1st row, 1st col (top-left element of matrix)

two_d_array[1][0] = 2
print two_d_array[1][0]  # prints 2   # 2nd row, 1st col

two_d_array[1][4] = 3
print two_d_array[1][4]  # prints 3   # 2nd row, last col

two_d_array[4][4] = 4
print two_d_array[4][4]  # prints 4   # last row, last col (right, bottom element of matrix)

13

Verwenden:

matrix = [[0]*5 for i in range(5)]

Die * 5 für die erste Dimension funktioniert, da auf dieser Ebene die Daten unveränderlich sind.


5
Ich würde dies wahrscheinlich schreiben alsmatrix = [[0]*cols for _ in range(rows)]
Shital Shah

12

So deklarieren Sie eine Matrix von Nullen (Einsen):

numpy.zeros((x, y))

z.B

>>> numpy.zeros((3, 5))
    array([[ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.]])

oder numpy.ones ((x, y)) z

>>> np.ones((3, 5))
array([[ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.]])

Es sind sogar drei Dimensionen möglich. ( http://www.astro.ufl.edu/~warner/prog/python.html siehe -> Mehrdimensionale Arrays)


12

So erstelle ich normalerweise 2D-Arrays in Python.

col = 3
row = 4
array = [[0] * col for _ in range(row)]

Ich finde diese Syntax leicht zu merken, verglichen mit der Verwendung von zwei for-Schleifen in einem Listenverständnis.


11

Ich bin in meinem ersten Python-Skript und war durch das Beispiel mit der quadratischen Matrix ein wenig verwirrt. Ich hoffe, das folgende Beispiel hilft Ihnen dabei, Zeit zu sparen:

 # Creates a 2 x 5 matrix
 Matrix = [[0 for y in xrange(5)] for x in xrange(2)]

damit

Matrix[1][4] = 2 # Valid
Matrix[4][1] = 3 # IndexError: list index out of range

10

Mit NumPy können Sie eine leere Matrix wie folgt initialisieren:

import numpy as np
mm = np.matrix([])

Und später Daten wie folgt anhängen:

mm = np.append(mm, [[1,2]], axis=1)

Was wären die Vor- und Nachteile der Verwendung von Numpy anstelle von "Listenverständnis"?
Revolucion für Monica

7

Ich habe in Kommas getrennte Dateien wie folgt gelesen:

data=[]
for l in infile:
    l = split(',')
    data.append(l)

Die Liste "Daten" ist dann eine Liste von Listen mit Indexdaten [Zeile] [Spalte]


7

Wenn Sie es als 2D-Array betrachten möchten, anstatt gezwungen zu sein, in Form einer Liste von Listen zu denken (meiner Meinung nach viel natürlicher), können Sie Folgendes tun:

import numpy
Nx=3; Ny=4
my2Dlist= numpy.zeros((Nx,Ny)).tolist()

Das Ergebnis ist eine Liste (kein NumPy-Array), und Sie können die einzelnen Positionen mit Zahlen, Zeichenfolgen usw. überschreiben.


sind numpy.matrixgleich numpy.zerosohne Nullen ohne Liste?
Revolucion für Monica

6

Dafür ist das Wörterbuch gemacht!

matrix = {}

Sie können Schlüssel und Werte auf zwei Arten definieren:

matrix[0,0] = value

oder

matrix = { (0,0)  : value }

Ergebnis:

   [ value,  value,  value,  value,  value],
   [ value,  value,  value,  value,  value],
   ...

6

Verwenden:

import copy

def ndlist(*args, init=0):
    dp = init
    for x in reversed(args):
        dp = [copy.deepcopy(dp) for _ in range(x)]
    return dp

l = ndlist(1,2,3,4) # 4 dimensional list initialized with 0's
l[0][1][2][3] = 1

Ich denke, NumPy ist der richtige Weg. Das Obige ist generisch, wenn Sie NumPy nicht verwenden möchten.


Ich mag diesen Versuch, mit Vanille-Python etwas Einfaches zu machen, ohne numpy verwenden zu müssen.
Rick Henderson

4

mit Liste:

matrix_in_python  = [['Roy',80,75,85,90,95],['John',75,80,75,85,100],['Dave',80,80,80,90,95]]

Mit dict: Sie können diese Informationen auch in der Hash-Tabelle speichern, um schnell suchen zu können

matrix = { '1':[0,0] , '2':[0,1],'3':[0,2],'4' : [1,0],'5':[1,1],'6':[1,2],'7':[2,0],'8':[2,1],'9':[2,2]};

Matrix ['1'] gibt Ihnen das Ergebnis in O (1) Zeit

* nb : Sie müssen sich mit einer Kollision in der Hash-Tabelle befassen


4

Wenn Sie vor dem Start keine Größeninformationen haben, erstellen Sie zwei eindimensionale Listen.

list 1: To store rows
list 2: Actual two-dimensional matrix

Speichern Sie die gesamte Zeile in der 1. Liste. Wenn Sie fertig sind, fügen Sie Liste 1 in Liste 2 ein:

from random import randint

coordinates=[]
temp=[]
points=int(raw_input("Enter No Of Coordinates >"))
for i in range(0,points):
    randomx=randint(0,1000)
    randomy=randint(0,1000)
    temp=[]
    temp.append(randomx)
    temp.append(randomy)
    coordinates.append(temp)

print coordinates

Ausgabe:

Enter No Of Coordinates >4
[[522, 96], [378, 276], [349, 741], [238, 439]]

3
# Creates a list containing 5 lists initialized to 0
Matrix = [[0]*5]*5

Seien Sie vorsichtig mit diesem kurzen Ausdruck, siehe die vollständige Erklärung unten in der Antwort von @ FJ


19
Sei auf diese Weise vorsichtig, weil Matrix[0], Matrix[1], ..., Matrix[4]alle auf dem gleichen Array, so nach Matrix[0][0] = 3, die Sie erwarten würden Matrix[0][0] == Matrix[1][0] == ... == Matrix[4][0] == 3.
Gongzhitaao

1
Danke gongzhitaao für deinen Kommentar. Hätte ich es elier gelesen, hätte ich mindestens eine halbe Stunde gespart. Eine Matrix zu haben, in der jede Zeile auf dieselbe Stelle im Speicher verweist, scheint nicht sehr nützlich zu sein, und wenn Sie nicht wissen, was Sie tun es ist sogar gefährlich! Ich bin mir ziemlich sicher, dass Masoud Abasian, der die Frage gestellt hat, dies NICHT tun möchte.
Adrian

7
Sie sollten diese Antwort entfernen, da sie nicht korrekt ist. Anfänger könnten verwirrt sein.
cxxl

2
Auf welche Antwort beziehen Sie sich? Ich sehe keinen Benutzer mit dem Namen "FJ" (nicht einmal in gelöschten Antworten).
Peter Mortensen

3
l=[[0]*(L) for _ in range(W)]

Wird schneller sein als:

l = [[0 for x in range(L)] for y in range(W)] 

2
Doppelte Antwort von einer bereits unten beantworteten. Auch [[0]*(L) for i in range(W)]sollte [[0]*(L) for _ in range(W)]da inirgendwo verwendet werden
Ayush Vatsyayan

2

Sie können eine leere zweidimensionale Liste erstellen, indem Sie zwei oder mehr eckige Klammern oder dritte Klammern ( []durch Komma getrennt) mit einer quadratischen Klammer verschachteln , wie unten dargestellt:

Matrix = [[], []]

Angenommen, Sie möchten 1 anhängen und Matrix[0][0]dann Folgendes eingeben:

Matrix[0].append(1)

Geben Sie nun Matrix ein und drücken Sie die Eingabetaste. Die Ausgabe wird sein:

[[1], []]

1

Versuche dies:

rows = int(input('Enter rows\n'))
my_list = []
for i in range(rows):
    my_list.append(list(map(int, input().split())))

1

Wenn Sie eine Matrix mit vordefinierten Zahlen benötigen, können Sie den folgenden Code verwenden:

def matrix(rows, cols, start=0):
    return [[c + start + r * cols for c in range(cols)] for r in range(rows)]


assert matrix(2, 3, 1) == [[1, 2, 3], [4, 5, 6]]

1

Hier ist das Code-Snippet zum Erstellen einer Matrix in Python:

# get the input rows and cols
rows = int(input("rows : "))
cols = int(input("Cols : "))

# initialize the list
l=[[0]*cols for i in range(rows)]

# fill some random values in it
for i in range(0,rows):
    for j in range(0,cols):
        l[i][j] = i+j

# print the list
for i in range(0,rows):
    print()
    for j in range(0,cols):
        print(l[i][j],end=" ")

Bitte schlagen Sie vor, wenn ich etwas verpasst habe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.