Je commence python et j'essaie d'utiliser une liste à deux dimensions, que je remplis initialement avec la même variable à chaque endroit. Je suis venu avec ceci:
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 = []
Cela donne le résultat souhaité, mais ressemble à une solution de contournement. Y a-t-il un moyen plus facile/plus court/plus élégant de le faire?
Un motif qui revenait souvent en Python était
bar = []
for item in some_iterable:
bar.append(SOME EXPRESSION)
qui a contribué à motiver l'introduction de la compréhension de liste, qui convertit cet extrait en
bar = [SOME EXPRESSION for item in some_iterable]
ce qui est plus court et parfois plus clair. Habituellement, vous prenez l'habitude de les reconnaître et de remplacer souvent les boucles par des compréhensions.
Votre code suit ce modèle deux fois
twod_list = [] \
for i in range (0, 10): \
new = [] \ can be replaced } this too
for j in range (0, 10): } with a list /
new.append(foo) / comprehension /
twod_list.append(new) /
Vous pouvez utiliser une compréhension list :
x = [[foo for i in range(10)] for j in range(10)]
# x is now a 10x10 array of 'foo' (which can depend on i and j if you want)
Cette manière est plus rapide que les compréhensions de liste imbriquées
[x[:] for x in [[foo] * 10] * 10] # for immutable foo!
Voici quelques timings python3, pour les petites et grandes listes
$python3 -m timeit '[x[:] for x in [[1] * 10] * 10]'
1000000 loops, best of 3: 1.55 usec per loop
$ python3 -m timeit '[[1 for i in range(10)] for j in range(10)]'
100000 loops, best of 3: 6.44 usec per loop
$ python3 -m timeit '[x[:] for x in [[1] * 1000] * 1000]'
100 loops, best of 3: 5.5 msec per loop
$ python3 -m timeit '[[1 for i in range(1000)] for j in range(1000)]'
10 loops, best of 3: 27 msec per loop
Explication:
[[foo]*10]*10
crée une liste du même objet répété 10 fois. Vous ne pouvez pas simplement utiliser ceci, car la modification d'un élément modifiera ce même élément dans chaque ligne!
x[:]
est équivalent à list(X)
mais est un peu plus efficace puisqu'il évite la recherche de nom. Dans les deux cas, il crée une copie superficielle de chaque ligne, de sorte que tous les éléments sont désormais indépendants.
Tous les éléments sont le même objet foo
, donc sifoo
est mutable , vous ne pouvez pas utiliser ce schéma.
import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]
ou en supposant une classe (ou fonction) Foo
qui retourne foo
s
[[Foo() for x in range(10)] for y in range(10)]
N'utilisez pas [[v] * n] * n, c'est un piège!
>>> 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]]
mais t = [[0] * 3 pour i dans l'intervalle (3)] est excellent
Pour initialiser un tableau à deux dimensions en Python:
a = [[0 for x in range(columns)] for y in range(rows)]
[[foo for x in xrange(10)] for y in xrange(10)]
Généralement, lorsque vous voulez des tableaux multidimensionnels, vous ne voulez pas une liste de listes, mais plutôt un tableau numpy ou éventuellement un dict.
Par exemple, avec numpy vous feriez quelque chose comme
import numpy
a = numpy.empty((10, 10))
a.fill(foo)
Vous pouvez faire juste ceci:
[[element] * numcols] * numrows
Par exemple:
>>> [['a'] *3] * 2
[['a', 'a', 'a'], ['a', 'a', 'a']]
Mais cela a un effet secondaire indésirable:
>>> b = [['a']*3]*3
>>> b
[['a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']]
>>> b[1][1]
'a'
>>> b[1][1] = 'b'
>>> b
[['a', 'b', 'a'], ['a', 'b', 'a'], ['a', 'b', 'a']]
Si c'est un tableau peu peuplé, vous feriez mieux d'utiliser un dictionnaire avec un tuple:
dict = {}
key = (a,b)
dict[key] = value
...
utilisez le plus simple de penser pour créer cela.
wtod_list = []
et ajoutez la taille:
wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]
ou si nous voulons déclarer la taille en premier. nous n'utilisons que:
wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]
t = [ [0]*10 for i in [0]*10]
pour chaque élément, un nouveau [0]*10
sera créé.
twod_list = [[foo for _ in range(m)] for _ in range(n)]
pour n est le nombre de lignes et m est le nombre de colonnes et foo est la valeur.
>>> m, n = map(int, raw_input().split())
5 5
>>> x[0][0] = 34
>>> x
[[34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None]]
>>> id(x[0][0])
140416461589776
>>> id(x[3][0])
140416461589776
Avec cette approche, python ne permet pas de créer un espace d'adressage différent pour les colonnes externes et entraîne divers problèmes de comportement que ceux que vous attendez.
y = [[0 for i in range(m)] for j in range(n)]
>>> id(y[0][0]) == id(y[1][0])
False
C'est une bonne approche mais il y a une exception si vous définissez la valeur par défaut sur None
>>> r = [[None for i in range(5)] for j in range(5)]
>>> r
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
>>> id(r[0][0]) == id(r[2][0])
True
Donc, définissez correctement votre valeur par défaut en utilisant cette approche.
Suivez la réponse du micro de double boucle .
Matrix={}
for i in range(0,3):
for j in range(0,3):
Matrix[i,j] = raw_input("Enter the matrix:")
Comme @Arnab et @Mike l'ont souligné, un tableau n'est pas une liste. Peu de différences sont 1) les tableaux ont une taille fixe pendant l'initialisation 2) les tableaux supportent normalement des opérations moins importantes qu'une liste.
Peut-être un peu exagéré dans la plupart des cas, mais voici une implémentation de matrice 2d basique qui exploite la mise en œuvre de matrice matérielle à l'aide de ctypes python
import ctypes
class Array:
def __init__(self,size,foo): #foo is the initial value
self._size = size
ArrayType = ctypes.py_object * size
self._array = ArrayType()
for i in range(size):
self._array[i] = foo
def __getitem__(self,index):
return self._array[index]
def __setitem__(self,index,value):
self._array[index] = value
def __len__(self):
return self._size
class TwoDArray:
def __init__(self,columns,rows,foo):
self._2dArray = Array(rows,foo)
for i in range(rows):
self._2dArray[i] = Array(columns,foo)
def numRows(self):
return len(self._2dArray)
def numCols(self):
return len((self._2dArray)[0])
def __getitem__(self,indexTuple):
row = indexTuple[0]
col = indexTuple[1]
assert row >= 0 and row < self.numRows() \
and col >=0 and col < self.numCols(),\
"Array script out of range"
return ((self._2dArray)[row])[col]
if(__== "__main__"):
twodArray = TwoDArray(4,5,5)#sample input
print(twodArray[2,3])
Vous pouvez essayer ceci [[0] * 10] * 10. Cela retournera le tableau 2D de 10 lignes et 10 colonnes avec la valeur 0 pour chaque cellule.
C'est le meilleur que j'ai trouvé pour enseigner aux nouveaux programmeurs, sans utiliser de bibliothèques supplémentaires. J'aimerais quelque chose de mieux cependant.
def initialize_twodlist(value):
list=[]
for row in range(10):
list.append([value]*10)
return list
Le modèle général pour ajouter des dimensions pourrait être tiré de cette série:
x = 0
mat1 = []
for i in range(3):
mat1.append(x)
x+=1
print(mat1)
x=0
mat2 = []
for i in range(3):
tmp = []
for j in range(4):
tmp.append(x)
x+=1
mat2.append(tmp)
print(mat2)
x=0
mat3 = []
for i in range(3):
tmp = []
for j in range(4):
tmp2 = []
for k in range(5):
tmp2.append(x)
x+=1
tmp.append(tmp2)
mat3.append(tmp)
print(mat3)
La chose importante que j'ai comprise est la suivante: lors de l'initialisation d'un tableau (dans n'importe quelle dimension), nous devrions attribuer une valeur par défaut à toutes les positions du tableau. Ensuite, seule l'initialisation est terminée. Après cela, nous pouvons modifier ou recevoir de nouvelles valeurs à n’importe quelle position du tableau. Le code ci-dessous a parfaitement fonctionné pour moi
N=7
F=2
#INITIALIZATION of 7 x 2 array with deafult value as 0
ar=[[0]*F for x in range(N)]
#RECEIVING NEW VALUES TO THE INITIALIZED ARRAY
for i in range(N):
for j in range(F):
ar[i][j]=int(input())
print(ar)
Voici un moyen plus simple:
import numpy as np
twoD = np.array([[]*m]*n)
Pour initialiser toutes les cellules avec une valeur 'x', utilisez:
twoD = np.array([[x]*m]*n