Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

remplir un tableau

7 réponses
Avatar
Fabrice
Bonjour,

je voulais remplir un tableau avec des nombres aléatoires mais j'ai 50
fois la même ligne !

j'ai fait :

import matplotlib.pyplot as plt
import random

image = [[0]*50]*50

for ligne in range(50):
for pixel in range(50):
image[ligne][pixel] = random.randint(0, 10)

plt.imshow(image,cmap='gray')
plt.show()

Pourquoi ?

Merci,
Fabrice.

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus

7 réponses

Avatar
Benoit Izac
Bonjour,
Le 29/01/2018 à 23:39, Fabrice a écrit dans le message
<5a6fa2b6$0$7180$ :
je voulais remplir un tableau avec des nombres aléatoires mais j'ai 50
fois la même ligne !
j'ai fait :
import matplotlib.pyplot as plt
import random
image = [[0]*50]*50

Le problème est là. Tu crées une liste contenant 50 fois une référence
vers la même liste qui contient 50 zéros :
image = [[0]*50]*50
id(image[0])



140001800012424
id(image[1])



140001800012424
Alors qu'en faisant comme cela :
image = [[0]*50 for _ in range(50)]
id(image[0])



140001800012936
id(image[1])



140001800012744
--
Benoit Izac
Avatar
Nicolas
Bonjour,
Pour mieux comprendre la réponse de Benoit, il faut bien comprendre la
notion de variables mutables et non mutables :
http://sametmax.com/valeurs-et-references-en-python/
Sinon :
- La largeur et la hauteur de l'image devraient être des variables.
D'une part, c'est plus compréhensible, et d'autre part, cela évite les
erreurs lorsque l'une ou l'autre sera modifiée.
largeur = 50
hauteur = 50
image = [[0]*largeur for _ in range(hauteur)]
for ligne in range(hauteur):
for pixel in range(largeur):
image[ligne][pixel] = random.randint(0, 10)
- Une petite amélioration est d'utiliser les tailles des listes pour les
parcourir :
largeur = 50
hauteur = 50
image = [[0]*largeur for _ in range(hauteur)]
for ligne in range(len(image)):
for pixel in range(len(image[0])):
image[ligne][pixel] = random.randint(0, 10)
- Mais pas besoin de créer les listes avant de les remplir. Autant les
créer avec le bon contenu dès le départ :
largeur = 50
hauteur = 50
image = []
for ligne in range(hauteur) :
pixels = []
for pixel in range(largeur) :
pixels.append(random.randint(0, 10))
image.append(pixels)
- La même chose mais en plus pythonique :
largeur = 50
hauteur = 50
image = [[random.randint(0, 10) for _ in range(largeur)] for __ in
range(hauteur)]
A noter que les _ et __ n'ont rien de particulier. Ce sont des variables
comme les autres. On les utilise pour indiquer que ces variables ne
servent à rien si ce n'est à itérer dans la boucle for.
Nicolas
Avatar
marc.marc
Bonjour,
je ne réponds pas à la question, mais pour ce genre d'opération il vaut
bien mieux à mon avis utiliser les tableaux (arrays) numpy, sur lesquels
on peut de plus faire toutes sortes de calculs, que les listes:
import numpy as np
import pylab as pl
image = np.random.randint(low=0,high,size=(50,50))
pl.imshow(image,cmap="gray")
pl.show()
Amicalement.
Marc
Le 29/01/2018 à 23:39, Fabrice a écrit :
Bonjour,
je voulais remplir un tableau avec des nombres aléatoires mais j'ai 50
fois la même ligne !
j'ai fait :
import matplotlib.pyplot as plt
import random
image = [[0]*50]*50
for ligne in range(50):
    for pixel in range(50):
        image[ligne][pixel] = random.randint(0, 10)
plt.imshow(image,cmap='gray')
plt.show()
Pourquoi ?
Merci,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le
logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Fabrice
Le 30/01/2018 à 07:19, Benoit Izac a écrit :
image = [[0]*50]*50
id(image[0])



140001800012424
id(image[1])



140001800012424
Alors qu'en faisant comme cela :
image = [[0]*50 for _ in range(50)]
id(image[0])



140001800012936
id(image[1])



140001800012744

je suis surpris que [[0]*50]*50 et [[0]*50 for _ in range(50)] ne
fassent pas la même chose !
En tout cas merci Benoit,
cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Fabrice
Le 30/01/2018 à 09:53, Nicolas a écrit :
Bonjour,
Pour mieux comprendre la réponse de Benoit, il faut bien comprendre la
notion de variables mutables et non mutables :
http://sametmax.com/valeurs-et-references-en-python/

Le pire, c'est que j'ai suivi le MOOC fun Python 3 et que j'avais
entendu parler des objets mutables ou non :-(
J'adore la solution :
image = [[random.randint(0, 10) for _ in range(largeur)] for __ in
range(hauteur)]

Merci Nicolas pour votre réponse très pédagogique,
cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Fabrice
Le 31/01/2018 à 09:25, a écrit :
Bonjour,
je ne réponds pas à la question, mais pour ce genre d'opération il vaut
bien mieux à mon avis utiliser les tableaux (arrays) numpy, sur lesquels
on peut de plus faire toutes sortes de calculs, que les listes:

Sans répondre à la question explicite, vous répondez à une question non
formulée.
Je suis prof de maths et je dois enseigner l'algorithmique (un bien
grand mot pour ce niveau) en seconde.
Le programme conseille Python mais nous ne devons pas enseigner Python,
juste illustrer nos algos en programmant un peu.
Je dois donc rester très simple sur les subtilités de python.
Du coup, votre proposition d'utiliser numpy avec les "array" me semble
sympathique.
Merci pour cette piste,
cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Benoit Izac
Bonjour,
Le 31/01/2018 à 16:15, Fabrice a écrit dans le message
<5a71dd90$0$3420$ :
image = [[0]*50]*50
id(image[0])



140001800012424
id(image[1])



140001800012424
Alors qu'en faisant comme cela :
image = [[0]*50 for _ in range(50)]
id(image[0])



140001800012936
id(image[1])



140001800012744

je suis surpris que [[0]*50]*50 et [[0]*50 for _ in range(50)] ne
fassent pas la même chose !

[[0]*50]*50 : je crée un objet de type int qui vaut 0, puis une liste de
50 éléments qui référencent tous cet objet int(0), puis une liste de 50
éléments qui référencent tous cette unique liste [0]*50.
[[0]*50 for _ in range(50)] : je fais 50 fois "je crée un objet de int
qui vaut 0, puis une liste de 50 éléments qui référencent tous cet objet
int(0)" et je mets à chaque fois la référence dans une liste. C'est
donc équivalent à :
l = []
for _ in range(50):
l.append([0]*50)
--
Benoit Izac