Toutes mes excuses car je suis sûr que ce problème s'est déjà posé mais aucun des exemples ne semble s'appliquer.
J'essaie de créer une liste 2D (4 sur 100) qui attribue des valeurs aléatoires dans différentes plages dans chaque ligne.
29 21 2 0 29 21 2 0
Les sorties affichent simplement le même ensemble de nombres pour chaque ligne de la liste 2D ...
Sortie:
XXX
Je suis nouveau en python et je sais que je dois manquer quelque chose de fondamental, mais après beaucoup de umming et ahhing je ne l'ai pas compris, toute aide est appréciée. p >
Merci
3 Réponses :
Vous avez une liste qui contient 100 fois la même liste
import random size_of_meadow = 100 no_of_flowers = 100 no_of_flower_types = 3 flower = [] for row in range(no_of_flowers): flower.append([random.randint(0, size_of_meadow-1), random.randint(0, size_of_meadow-1), random.randint(1, no_of_flower_types), 1 if random.randint(0, 100) < 5 else 0]) print(flower[0][0]) print(flower[0][1]) print(flower[0][2]) print(flower[0][3]) print(" ") print(flower[1][0]) print(flower[1][1]) print(flower[1][2]) print(flower[1][3]) # Sorry the above isn't in a for loop
La meilleure solution sera
a=[0,0,0] flower=[a,a,a,a,...]
Cependant, le générateur de fleurs serait pair mieux
C'est génial et a produit les résultats que je voulais. Je ne comprends toujours pas tout à fait l'erreur que je faisais, mais j'irai de l'avant en utilisant cette méthode à l'avenir.
Hey @Lee a raison mais laissez-moi élaborer
flower = [[None for _ in range(5)] for _ in range(no_of_flowers)] >>> id(flower[0]) 4354853832 >>> id(flower[1]) 4354854600
Ici vous pouvez voir que chaque sous-liste pointera vers le même emplacement en mémoire
J'utiliserais cette méthode:
>>> flower = [[0] * 5] * 100 >>> flower[0] [0, 0, 0, 0, 0] >>> flower[1] [0, 0, 0, 0, 0] >>> id(flower[0]) 4354853640 >>> id(flower[1]) 4354853640
C'est ce que je pensais, mais pourquoi tous indiquent-ils la même position? En fait, je m'attendais à ce que [[0] * 5] * 100 s'exécute de la même manière que votre code.
Cette réponse a produit le résultat que je voulais en changeant simplement la ligne de code, ce qui est génial.
@epsilonmajorquezero lorsque vous exécutez [0] * 5
, il crée une liste [0, 0, 0, 0, 0]
puis le code * 100 > crée une liste dont la sous-liste pointe sur 100 positions. La compilation de liste est en fait réexécutée à chaque itération en créant de nouveaux éléments
@bison qui a rendu le problème vraiment clair, merci pour l'explication
Ouais, je vois que c'est ce qu'il faut faire en fonction du comportement mais alors le comportement n'est pas vraiment cohérent: d'abord [0] * 5 qui crée une liste de 5 zéros (qui ne sont pas au même emplacement en mémoire) mais ensuite cette liste se multiplie indique à nouveau la même position.
En utilisant [[0] * 5] * no_of_flowers
, vous créez 100 références à la même liste. Cela signifie qu'il y a UNE SEULE RANGÉE dans la mémoire.
Lorsque vous modifiez une ligne, si affecte la ligne en mémoire, et puisque toutes les autres «lignes» y font référence, ils utiliseront simplement la liste en mémoire qui est à jour.
Pour éviter ce scénario, vous pouvez utiliser:
>>> board = [['']*3 for _ in range(3)] >>> board[0][0] = "X" >>> board [['X', '', ''], ['', '', ''], ['', '', '']]
Vous pouvez trouver un exemple et explication en wtfpython :
XXX
Sortie:
>>> board [['', '', ''], ['', '', ''], ['', '', '']] >>> board[0] ['', '', ''] >>> board[0][0] '' >>> board[0][0] = "X" >>> board [['X', '', ''], ['X', '', ''], ['X', '', '']]
Explication:
Lorsque nous initialisons la ligne
, cette visualisation explique ce qui se passe dans la mémoire.
Et quand le board code> est initialisé en multipliant la
ligne
, c'est ce qui se passe à l'intérieur de la mémoire (chacun des éléments board [0]
, board [1] code > et
board [2] cod e> est une référence à la même liste référencée par
row
)
Nous pouvons éviter cela scénario ici en n'utilisant pas la variable row
pour générer le board
. (Question posée dans ce numéro).
# Let's initialize a row row = [""]*3 #row i['', '', ''] # Let's make a board board = [row]*3
print ('\ n'.join ([' '. join ([' {} '.format (élément) pour l'élément dans la ligne]) pour la ligne dans la fleur]))
cela peut également être utileCopie possible de Liste des modifications de listes reflétées de manière inattendue dans les sous-listes