Bonjour,
Dans un programme, j'ai besoin de modéliser une carte en 2D donc j'utilise pour ça des listes imbriquées de la façon suivante
# Création de ma map
carte = []
iy = []
for y in range(30):
iy.append("t") # t signifie que la case en question est du terrain
for x in range(30):
carte.append(iy)
Pour modifier un emplacement je comptais faire la chose suivante :
carte[x][y] = f # pour placer à la case de coordonées (x,y) la lettre f # (pour fourmi)
Hors cela me change la valeur de y pour toutes les lignes de x, par exemple en supposant que j'ai le tableau suivant :
t t t t t
t t t t t
t t t t t
avec carte[2][2] = "f", je me retrouve avec le tableau suivant :
t t f t t
t t f t t
t t f t t
alors que je voudrais obtenir
t t t t t
t t t t t
t t f t t
Et je ne vois vraiment pas pourquoi ça me fais ça ;(
Merci
# Re: Tableau à 2 dimensions
Posté par zelyph . Évalué à 6.
for x in range(30):
carte.append(iy)
ca ajoute une référence/pointeur vers iy dans le tableau carte et non pas une copie de iy, donc si tu modifie une ligne tu modifie iy, c'est à dire toutes les lignes
[^] # Re: Tableau à 2 dimensions
Posté par Ramso . Évalué à 1.
# Création de ma map
carte = []
iy = []
for y in range(30):
iy.append("t")
for x in range(30):
carte.append(iy[:])
iy[:] est une copie de iy
l'ajout de "t" ajoute aussi des références vers la même chaîne "t" mais dans ce sens là, ça va
[^] # Re: Tableau à 2 dimensions
Posté par Ramso . Évalué à 1.
sinon je te propose une technique dictionnairienne :
carte = {}
carte((x, y)) = "t"
case = carte.setdefault((x,y), "t")
vaut la valeur stockée à la clé (x, y) ou alors "t" par défaut
si tu préfère la bonne vieille initialisation :
carte = {}
for y in range(30):
for x in range(30):
carte((x, y)) = "t"
# Re: Tableau à 2 dimensions
Posté par Epsos . Évalué à 3.
1- tu ne construit qu'une seule variable iy
2- dans ta boucle d'affectation 'carte.append(iy)', si iy est partage (alors que tu voudrais qu'il soit duplique), alors
3- CQFD
Donc, soit tu te debrouilles pour faire un truc du style :
carte.append(iy.clone())
ou
carte.append(iy.copy())
ou whatever du moment que tu duplique
ou bien tu change ta boucle en : (duplication a la main)
for x in range(30):
{
iy = []
for y in range(30):
{
iy.append("t") # t signifie que la case en question est du terrain
}
carte.append(iy)
}
J'ai rajoute des accolades pour la clarte ...
[^] # Re: Tableau à 2 dimensions
Posté par Fabien (site web personnel) . Évalué à 1.
# Re: Tableau à 2 dimensions
Posté par Pascal Terjan (site web personnel) . Évalué à 2.
[^] # Re: Tableau à 2 dimensions
Posté par Fabien (site web personnel) . Évalué à 1.
Désolé, je l'avais oublié
[^] # Re: Tableau à 2 dimensions
Posté par Ramso . Évalué à 0.
pfff t'as même pas reconnu :)
et pourtant... avec cette syntaxe claire et simple, à tel point que les gens* ont pu voir l'erreur d'algo sans connaître le langage, ça ne pouvait être que du python :)
bon d'accord, templeet a viré l'identation...
(*) oui bon, j'ai répondu trop vite mais je me suis rattrapé avec une autre solution :)
# Re: Tableau à 2 dimensions
Posté par Pascal Terjan (site web personnel) . Évalué à 0.
t t t t t
t t t t t
t t f t t
pas plutot ca ?
t t t t t
t t f t t
t t f t t
[^] # Re: Tableau à 2 dimensions
Posté par Pascal Terjan (site web personnel) . Évalué à 1.
# Merci à tous
Posté par Fabien (site web personnel) . Évalué à 2.
# Python est formidable
Posté par schyzomarijks . Évalué à 3.
x=['t']
map=[]
for i in xrange( 30 )
.....map.append( x*30)
et voilà
[^] # Re: Python est formidable
Posté par Ramso . Évalué à 2.
ou sinon avec une variable de moins :
map = []
for i in range(30):
map.append(['t] * 30)
bon j'ai vérifié et ça utilise bien autant de références que d'itérations de i, contrairement à la première version.
[^] # Re: Python est formidable
Posté par schyzomarijks . Évalué à 2.
e=['t']
carte = [e*30 for i in xrange(30)]
[^] # Re: Python est formidable
Posté par Ramso . Évalué à 2.
map = [['t'] * 30 for i in range(30)]
bon on devrait arrêter là avant que les gens commencent à croire que python a les mêmes travers (de porc ?) que perl :)
[^] # Re: Python est formidable
Posté par Epsos . Évalué à 1.
[^] # Re: Python est formidable
Posté par Ramso . Évalué à 2.
pour la peine je fais encore plus simple :
carte = [['t'] * 30] * 30
mouhahaha !
et la version dictionnaire :
carte = {}
[carte.setdefault((x,y), 't') for x in range(30) for y in range(30)]
bon il est temps que je rentre chez moi...
[^] # Re: Python est formidable
Posté par wismerhill . Évalué à 3.
WAW, elle est superbe celle-là!
Beaucoup plus compact que ce qu'on pourrais faire en C et beaucoup plus clair à la fois.
[^] # Re: Python est formidable
Posté par Vivi (site web personnel) . Évalué à 1.
[^] # Re: Python est formidable
Posté par Ramso . Évalué à 1.
'vais aller me fouetter tiens !
ou alors...
carte = [['t'][:] * 30][:] * 30
là je devrais être tranquille :)
heu... en fait je vais aller me coucher... la journée a été longue... connerie de rer !
[^] # Re: Python est formidable
Posté par Vivi (site web personnel) . Évalué à 2.
Pour moi, le plus simple reste :
[ ['t' for i in range(30)] for j in range(30) ]
ou à la rigueur :
[ ['t] * 30 for i in range(30) ]
# Démasqué !!!
Posté par Fabimaru (site web personnel) . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.