python affecter des valeurs à la liste des éléments dans la boucle
Est-ce un python de comportement? Je pense que le résultat final devrait être [0,0,0] et la fonction id() doit retourner des valeurs identiques à chaque itération. Comment faire pythonic, et ne pas utiliser d'énumérer ou range(len(bar)?
bar = [1,2,3]
print bar
for foo in bar:
print id (foo)
foo=0
print id(foo)
print bar
de sortie:
[1, 2, 3]
5169664
5169676
5169652
5169676
5169640
5169676
[1, 2, 3]
OriginalL'auteur Chris | 2013-12-19
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, vous ne pouvez pas réaffecter une variable de boucle—eh bien, vous pouvez, mais ça ne changera pas la liste, vous êtes à parcourir. Le choix de
foo = 0
ne changera pas la liste, mais seulement la variable localefoo
(qui contient la valeur de l'itération au début de chaque itération).Prochaine chose, le petit nombre, comme
0
et1
en interne sont conservés dans une piscine de petit entier des objets (C'est un Disponible de la mise en œuvre du détail, ne doit pas être le cas!) C'est pourquoi l'ID est le même pourfoo
après l'affectation de0
. L'id est, fondamentalement, l'id de l'objet integer0
dans la piscine.Si vous souhaitez modifier votre liste lors de l'itération sur elle, vous n'avez malheureusement pour accéder aux éléments par index. Donc, si vous voulez garder la sortie le même, mais ont
[0, 0, 0]
à la fin, vous devrez effectuer une itération sur les indices:Sinon, c'est pas vraiment possible, car dès que vous stocker une liste de l'élément dans une variable, vous avez une référence distincte de ce qui est non lié à celui stocké dans la liste. Et comme la plupart de ces objets sont immuables et que vous créez un nouvel objet lors de l'affectation d'une valeur à une variable, vous n'aurez pas de liste de référence pour la mise à jour.
5169664
, cela serait catastrophique car elle voudrait changer de tous variable qui est actuellement fixé à 1.enumerate
peut-être mieux que la solution aveclen(bar)
.Je pense que c'est la bonne réponse à la partie de la question:Pourquoi est-il produit? pour Ce qui est de la pythonic façon de le faire? voir @Kevin répondre
La documentation de l'ID dit, "Retourner “l'identité” d'un objet. C'est un entier qui est garanti pour être unique et constante pour cet objet pendant sa durée de vie. Deux objets avec des non-cumul des durées de vie peuvent avoir le même id() de la valeur". Cette lecture, je suis surpris que l'id(foo) ne change jamais.
Pour les autres personnes qui pourraient rencontrer cette question: à Noter que même si l'objet dans la liste, vous faites allusion à l'est de mutable, alors vous pouvez réellement mettre à jour à travers cette variable
i
, par exemple, par le biais de+=
(__iadd__
). Voir stackoverflow.com/questions/41446833/...OriginalL'auteur poke
Oui, la sortie que vous obtenez est le Python ordinaire comportement. Affecter une nouvelle valeur à
foo
va changer foo id, et ne pas changer les valeurs stockées dansbar
.Si vous voulez juste une liste de zéros, vous pouvez le faire:
Si vous voulez faire un peu plus compliqué logique, où la nouvelle affectation dépend de l'ancienne valeur, vous pouvez utiliser une liste de compréhension:
Ou vous pouvez utiliser
map
:OriginalL'auteur Kevin
vous fait na pas changer la liste à tous.
la première chose pour que la boucle n'était d'attribuer bar[0] foo(l'équivalent de foo = bar[0]). toto est juste une référence à 1. Vous pouvez ensuite affecter un autre onject 0 à toto. Cela a changé la référence de foo à 0. Mais vous n'avez pas de barre de modification[0]. Rappelez-vous, foo comme une variable, les références de la barre[0], mais attribuer une autre valeur/objet toto n'a pas d'incidence sur la barre[0].
OriginalL'auteur Twisted Meadow
Réponse longue :
foo
est juste un nom local, une nouvelle liaison n'a pas d'impact sur la liste. Python variables sont vraiment juste la clé:des paires de valeurs, pas des noms symboliques pour les emplacements de mémoire.yep droit. Édité le fragment de code.
OriginalL'auteur bruno desthuilliers