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 = []
Il donne le résultat souhaité, mais ressemble à une solution de contournement. Existe-t-il une manière plus simple / plus courte / plus élégante de procéder?
python
multidimensional-array
thepandaatemyface
la source
la source
Réponses:
Un modèle qui est souvent apparu en Python était
qui a contribué à motiver l'introduction de listes de compréhension, qui convertissent cet extrait en
ce qui est plus court et parfois plus clair. Habituellement, vous avez l'habitude de les reconnaître et de remplacer souvent les boucles par des compréhensions.
Votre code suit ce modèle deux fois
la source
[foo] * 10
est une liste avec le même exactfoo
10 fois, ce qui peut ou non être important.[foo] * 10
: Cela veut dire que cela ne fonctionnera pas si vous remplissez un tableau avec des nombres aléatoires (évalue[random.randint(1,2)] * 10
à[1] * 10
ou[2] * 10
qui signifie que vous obtenez un tableau de tous les 1 ou 2 s, au lieu d'un tableau aléatoire.Vous pouvez utiliser une liste de compréhension :
la source
i
lignes et lesj
colonnes, je pense qu'il devrait être préférable de permuteri
etj
dans votre syntaxe pour une meilleure compréhension et changer la plage en 2 nombres différents.Ne l'utilisez pas
[[v]*n]*n
, c'est un piège!mais
fonctionne très bien.
la source
*
copieaddress
l'objet (liste).[[0] * col for _ in range(row)]
.Cette méthode est plus rapide que les compréhensions de listes imbriquées
Voici quelques timings python3, pour les petites et grandes listes
Explication:
[[foo]*10]*10
crée une liste du même objet répétée 10 fois. Vous ne pouvez pas simplement l'utiliser, car la modification d'un élément modifiera ce même élément dans chaque ligne!x[:]
est équivalentlist(X)
mais est un peu plus efficace car il évite la recherche de nom. Quoi qu'il en soit, il crée une copie superficielle de chaque ligne, donc maintenant tous les éléments sont indépendants.foo
Cependant, tous les éléments sont le même objet, donc s'ilfoo
est modifiable , vous ne pouvez pas utiliser ce schéma., Vous devez utiliserou en supposant une classe (ou fonction)
Foo
qui renvoiefoo
sla source
copy.deepcopy
. Vous avez besoin d'un plan spécifique à vos données si vous avez un objet mutable arbitraire.x
ety
. Cela ne devrait-il pas être[[copy.deepcopy(foo) for y in range(10)] for x in range(10)]
[foo]*10
ne crée pas 10 objets différents - mais il est facile d'oublier la différence dans le cas où foo est immuable, comme unint
oustr
.Pour initialiser un tableau bidimensionnel en Python:
la source
a = [[0 for x in range(columns)] for y in range(rows)]
.la source
[[0] * col] * row
ne faites pas ce que vous voulez est que lorsque vous initialisez une liste 2D de cette façon, Python ne créera pas de copies distinctes de chaque ligne. Au lieu de cela, il lancera la liste externe avec des pointeurs vers la même copie de[0]*col
. Toute modification que vous apportez à l'une des lignes sera alors reflétée dans les lignes restantes car elles pointent toutes vers les mêmes données en mémoire.Habituellement, 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
la source
numpy
soit génial, je pense que cela pourrait être un peu exagéré pour un débutant.numpy
. +1Vous pouvez faire juste ceci:
Par exemple:
Mais cela a un effet secondaire indésirable:
la source
pour n est le nombre de lignes, et m est le nombre de colonnes, et foo est la valeur.
la source
S'il s'agit d'un tableau peu peuplé, il serait préférable d'utiliser un dictionnaire composé d'un tuple:
la source
pour chaque élément un nouveau
[0]*10
sera créé.la source
Approche incorrecte: [[Aucun * m] * n]
Avec cette approche, python ne permet pas de créer un espace d'adressage différent pour les colonnes externes et entraînera divers comportements inappropriés que vous attendez.
Approche correcte mais avec exception:
C'est une bonne approche mais il y a une exception si vous définissez la valeur par défaut sur
None
Définissez donc correctement votre valeur par défaut en utilisant cette approche.
Absolument correct:
Suivez la réponse du micro à double boucle .
la source
la source
Pour initialiser un tableau à 2 dimensions, utilisez:
arr = [[]*m for i in range(n)]
en fait,
arr = [[]*m]*n
créera un tableau 2D dans lequel tous les n tableaux pointeront vers le même tableau, donc tout changement de valeur dans n'importe quel élément sera reflété dans toutes les n listespour plus d'explications, visitez: https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
la source
utilisez la pensée la plus simple pour créer cela.
et ajoutez la taille:
ou si nous voulons d'abord déclarer la taille. nous utilisons uniquement:
la source
Comme l'ont souligné @Arnab et @Mike, un tableau n'est pas une liste. Peu de différences sont 1) les tableaux sont de taille fixe lors de l'initialisation 2) les tableaux prennent normalement en charge moins d'opérations qu'une liste.
Peut-être une surpuissance dans la plupart des cas, mais voici une implémentation de tableau 2D de base qui tire parti de l'implémentation de tableau matériel à l'aide de ctypes python (bibliothèques c)
la source
La chose importante que j'ai comprise est: lors de l'initialisation d'un tableau (dans n'importe quelle dimension) Nous devons donner une valeur par défaut à toutes les positions du tableau. Ensuite, seule l'initialisation se termine. Après cela, nous pouvons changer ou recevoir de nouvelles valeurs à n'importe quelle position du tableau. Le code ci-dessous a parfaitement fonctionné pour moi
la source
Si vous utilisez numpy , vous pouvez facilement créer des tableaux 2D :
X
la source
Ce qui précède vous donnera un tableau 2D 5x5
Il utilise la compréhension de liste imbriquée. Répartition comme ci-dessous:
[x] * col -> expression finale évaluée
pour x in -> x sera la valeur fournie par l'itérateur
[b pour b dans la plage (ligne)]] -> Itérateur.
[b pour b dans la plage (ligne)]] ceci évaluera à [0,1,2,3,4] puisque ligne = 5
alors maintenant il se simplifie pour
Cela évaluera à [[0] * 5 pour x dans [0,1,2,3,4]] -> avec x = 0 1ère itération
[[1] * 5 pour x dans [0,1,2, 3,4]] -> avec x = 1 2e itération
[[2] * 5 pour x dans [0,1,2,3,4]] -> avec x = 2 3e itération
[[3] * 5 pour x dans [0,1,2,3,4]] -> avec x = 3 4ème itération
[[4] * 5 pour x dans [0,1,2,3,4]] -> avec x = 4 5ème itération
la source
C'est le meilleur que j'ai trouvé pour enseigner aux nouveaux programmeurs, et sans utiliser de bibliothèques supplémentaires. J'aimerais quelque chose de mieux cependant.
la source
Voici un moyen plus simple:
Pour initialiser toutes les cellules avec une valeur 'x', utilisez:
la source
J'utilise souvent cette approche pour initialiser un tableau à 2 dimensions
n=[[int(x) for x in input().split()] for i in range(int(input())]
la source
Le modèle général pour ajouter des dimensions pourrait être tiré de cette série:
la source
Vous pouvez essayer ceci [[0] * 10] * 10. Cela renverra le tableau 2D de 10 lignes et 10 colonnes avec la valeur 0 pour chaque cellule.
la source
a = [[0]*10]*10
et quea[0][0] = 1
vous verrez alors le premier élément de chaque ligne maintenant égal à 1lst = [[0] * m pour i dans la plage (n)]
initialiser toutes les matrices n = lignes et m = colonnes
la source
Une autre façon consiste à utiliser un dictionnaire pour contenir un tableau à deux dimensions.
Cela peut simplement contenir n'importe quelle valeur 1D, 2D et pour l'initialiser à
0
ou toute autre valeur int, utilisez des collections .la source
Code:
initial_val
doit être immuable.la source
la source