web-dev-qa-db-fra.com

Comment initialiser un tableau à deux dimensions en Python?

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?

214

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)                           /
328
Mike Graham

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)
174
Adam Rosenfield

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 foos

[[Foo() for x in range(10)] for y in range(10)]
119
John La Rooy

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

58
Jason CHAN

Pour initialiser un tableau à deux dimensions en Python:

a = [[0 for x in range(columns)] for y in range(rows)]
46
Vipul
[[foo for x in xrange(10)] for y in xrange(10)]
24

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)
20
Mike Graham

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']]
12
hithwen

Si c'est un tableau peu peuplé, vous feriez mieux d'utiliser un dictionnaire avec un tuple:

dict = {}
key = (a,b)
dict[key] = value
...
8
btk

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)]
3
indi60
t = [ [0]*10 for i in [0]*10]

pour chaque élément, un nouveau [0]*10 sera créé.

3
user9269722
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.

3
Moustafa Saleh

Approche incorrecte: [[Aucun * m] * n]

>>> 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.

Approche correcte mais avec exception:

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.

Absolue correcte:

Suivez la réponse du micro de double boucle .

3
patilnitin
Matrix={}
for i in range(0,3):
  for j in range(0,3):
    Matrix[i,j] = raw_input("Enter the matrix:")
2
Sparsh

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])
1
Antony Thomas

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. 

0
ishant

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
0

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)
0
juanfal

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)

0
Fairoos Ok

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
0
user3650331