webentwicklung-frage-antwort-db.com.de

Weisen Sie einer einzelnen Zelle in einem zweidimensionalen Python-Array einen Wert zu

Nehmen wir an, ich habe das folgende leere zweidimensionale Array in Python:

q = [[None]*5]*4

Ich möchte der ersten Zeile in der ersten Spalte von q den Wert 5 zuweisen. Instinktiv mache ich Folgendes:

q[0][0] = 5

Dies erzeugt jedoch:

 [[5, None, None, None, None], 
  [5, None, None, None, None], 
  [5, None, None, None, None], 
  [5, None, None, None, None]]

Das erste Element von every array wird mit 5 initialisiert, wobei ich dachte, dass nur das erste Element des ersten Arrays das Update erhalten würde. Ich habe zwei Fragen:

  1. Warum initialisiert Python den ersten Wert jedes Arrays und nicht nur den ersten?
  2. Gibt es einen besseren Weg, um das zu erreichen, was ich versuche?
20
Ben McCormack

Das tut nicht was Sie gehofft haben.

q = [[None]*5]*4

Es verwendet mehrfach list-Objekte. Wie Sie sehen, wenn Sie eine Zelle in einem wiederverwendeten Listenobjekt geändert haben.

Eine einzelne Liste mit dem Wert [None] wird fünfmal verwendet.

Eine einzelne Liste mit dem Wert [[None]*5] wird viermal verwendet.

q = [ [ None for i in range(5) ] for j in range(4) ]

Könnte mehr sein, wonach Sie suchen.

Dies vermeidet ausdrücklich die Wiederverwendung eines Listenobjekts.

In 80% der Fälle ist ein Wörterbuch das, was Sie wirklich wollten.

q = {}
q[0,0]= 5

Wird auch funktionieren. Sie beginnen nicht mit einem vordefinierten Raster von None-Werten. Aber es ist selten, sie überhaupt zu brauchen.

In Python 2.7 und höher können Sie dies tun.

q = { (i,j):0 for i in range(5) for j in range(4) }

Dadurch wird ein durch 2-Tupel indexiertes Gitter erstellt.

{(0, 1): 0, (1, 2): 0, (3, 2): 0, (0, 0): 0, (3, 3): 0, (3, 0): 0, (3, 1): 0, (2, 1): 0, (0, 2): 0, (2, 0): 0, (1, 3): 0, (2, 3): 0, (4, 3): 0, (2, 2): 0, (1, 0): 0, (4, 2): 0, (0, 3): 0, (4, 1): 0, (1, 1): 0, (4, 0): 0}
42
S.Lott

Der Grund dafür ist, dass Sie die Liste nur viermal dupliziert haben! Python erstellt diese Liste nicht jedes Mal neu, wenn Sie *4 ausführen. Es verwendet das gleiche Listenobjekt.

Um dies zu umgehen, müssen Sie zwingen, dass Python diese Liste jedes Mal für Sie neu erstellt:

[ [None] * 5 for i1 in range(4) ]

In diesem Fall verwende ich ein Listenverständnis.

6
Donald Miner
q = [[None]*5]*4
print(q)
q[1][1]=4
print(q)
q = [ [ None for i in range(5) ] for j in range(4) ]
q[1][1]=4
print(q)

ergebnis:

[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
[[None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None]]
[[None, None, None, None, None], [None, 4, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
4
Jin Thakur

Die Antwort ist einfach Nie verwenden 

q = [[None]*5]*4

wie wenn Sie eine Zuordnung machen 

q[0][1]=5 weist mehreren Zeilen in einer Spalte einen mehrmaligen Wert zu. try print (q)

eher verwenden 

q = { (i,j):0 for i in range(5) for j in range(4) }

dann wird q[0][1]=5 nur einmal vergeben try 

print(q)
1
Jin Thakur

Wenn Sie eine Liste und kein Wörterbuch verwenden möchten, wie von den anderen vorgeschlagen, können Sie Folgendes verwenden:

q[0] = [5,None,None,None,None]
0
manosbar

Warum initialisiert Python den ersten Wert jedes Arrays und nicht nur den ersten?

Weil sie dasselbe Array sind, auf das mehrfach verwiesen wird.

Gibt es einen besseren Weg, um das zu erreichen, was ich versuche?

Erstellen Sie die Struktur so, dass sich das äußere Array auf separate innere Arrays bezieht, anstatt eines erneut zu verwenden. Die anderen Antworten bieten Möglichkeiten.

0
Karl Knechtel

Die Antwort auf Frage Nr. 2: Die Verwendung von numpy ist eine Option. Siehe folgenden Code.

import numpy as np

# creating 2D array with nans
num_of_rows = 5
num_of_cols = 3
a = np.full((num_of_rows, num_of_cols), np.nan) 
#for zero vals: a = np.zeros((num_of_rows, num_of_cols))

# placing number 5 in row 3, col 1
value = [5]
position_row = 3
position_col = 1
# the put command below flattens the 2D array
position = [int(num_of_cols * position_row + position_col)] 
np.put(a, position, value)

ergebnis:

[[ nan  nan  nan]
 [ nan  nan  nan]
 [ nan  nan  nan]
 [ nan   5.  nan]
 [ nan  nan  nan]]
0
SDJ