8
votes

Modification d'un itérateur de liste dans Python Non autorisé?

Exemple simple: xxx pré>

impression p> xxx pré>

tandis que: p> xxx pré>

Imprimés P>

[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]


4 commentaires

Comme, ce code produirait un NameError car a n'est pas défini.


Vos exemples de code sont mauvais. D'où viennent les premiers à imprimer? Votre impression 'A' qui n'existe pas et il y a deux sorties.


quelque peu liée


Désolé gars, "A" devrait évidemment être "myList". Fixé dans le poteau.


6 Réponses :


0
votes

Dans le premier exemple, l'entier est copié dans Obj qui est augmenté de 1. La liste n'est pas modifiée.

Si vous utilisiez une instance de classe et effectueriez des opérations dessus, cela serait changé.


0 commentaires

1
votes

vous êtes confus. Considérez votre premier extrait: xxx

obj n'est pas une sorte de pointeur magique dans la liste. C'est une variable qui contient une référence à un objet qui se trouve également dans la myiste. obj + = 1 a pour effet d'augmenter la valeur stockée dans obj . Votre code ne fait alors rien avec cette valeur.

Pour être clair: il n'y a pas de copies dans cet exemple de code. Obj est une variable qui contient un objet dans la liste. C'est tout.


2 commentaires

Si obj serait un itérateur comme dans C ++, l'objet de la liste serait mis à jour. Mais apparemment, obj est une copie et des modifications sont ignorées après chaque itération. Apparemment, Python fait ce dernier, qui est ma question.


@ROBW: Répétez après moi: il n'y a pas d'exemplaire dans cet exemple de code. obj est une variable qui contient un objet dans la liste. C'est tout.



7
votes

La raison obj + = 1 code> ne fait pas ce qui vous attend est que cette instruction ne modifie pas obj code> en place. Au lieu de cela, il calcule la nouvelle valeur et rebinds em> la variable obj code> pour pointer sur la nouvelle valeur. Cela signifie que le contenu de la liste reste inchangé.

en général, il est est em> possible de modifier la liste tout en itération sur celui-ci en utilisant pour obj dans la myiste code>. Par exemple: P>

myList = [val+1 for val in myList]


2 commentaires

Merci pour votre réponse. J'ai déjà conclu que le obj itérateur n'est pas un itérateur comme en C ++ et la modification de l'objet ne modifie pas la liste. Ce que vous dites, c'est que obj est à nouveau lié au nouvel objet qui sera perdu dans la prochaine itération. Dégager!


Très bonne réponse! Il ne s'agit pas de «copie peu profonde» parlà par la réponse acceptée.



6
votes

dans pour obj dans myList: , dans chaque itération, obj est une copie (peu profonde) de l'élément dans myList . Donc, la modification du obj ne fait rien à myList S.

C'est différent avec le Perl pour mon $ obj (@mylist) {}


5 commentaires

Exactement, je comprends que maintenant. obj n'est pas un itérateur comme dans C ++, il s'agit essentiellement d'une copie de l'objet, qui est ignorée dans la prochaine itération. Ainsi, la modification ne peut être effectuée qu'avec l'accès global / direct de la liste.


@ROBW, obj n'est pas une copie et cette réponse est trompeuse. Obj - comme toutes les variables de Python - ressemble davantage à un pointeur en C / C ++. Voir la modification à Ma réponse .


Ade Yu, je rassemble lorsque vous dites "Copier" Vous voulez dire "copie de l'adresse de l'élément" plutôt que "copie de l'élément lui-même". Vous pourriez clarifier cela.


@senderle Oui. Dans Python, variables ne sont que des références à objets . Seules les variables sont copiées, mais les objets . C'est juste comme obj = myList [index] est arrivé au tout début de chaque itération. Donc, obj + = 1 n'affecte pas le myList [index] . Merci. Je vais améliorer ma déclaration de réponse.


pourrait ne pas être une copie peu profonde s'il s'agit d'une liste de listes



0
votes

La modification de la liste est autorisée. Vos exemples de code Arbove sont assez brassés ...

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
   myList[index] += 1
 print myList


1 commentaires

C'est vraiment ce que j'ai posté et ne répond rien.



6
votes

Je pense que vous avez mal compris quel est un "objet itérateur". Un pour code> boucle n'est pas un objet Itérateur. À toutes fins utiles, a une boucle comme celle-ci:

for i, x in enumerate(myList):
    myList[i] = some_func(x)


2 commentaires

Évidemment, Imprimer A doit être Imprimer MyList , j'ai réparé cela. Merci pour le pointeur de énumérable , très utile, évite de maintenir votre propre code pour l'index de la liste!


Être encore plus pythonique et concis, vous pouvez faire soit soit [quelque_func (x) pour x dans myMist] ou carte (quelque_func, myList) , bien que ceux-ci font des copies de la liste initiale.