Ceci est une question simple sur la façon dont Python gère les données et les variables. J'ai fait beaucoup d'expérimentations et j'ai énormément de python, sauf que cela continue de me trébucher:
[Modifier: j'ai séparé et réarrangé les exemples de clarté] p>
Exemple 1: strong> p> Exemple 2: strong> p> >>> a = [[1], 2]
>>> a[0:1][0][0]
1
>>> a[0:1][0][0] = 5
>>> a
[[5], 2] # Why now?
3 Réponses :
A [0: 1] renvoie un nouveau tableau contenant une référence à la matrice [1], vous finissez donc de modifier la matrice interne via un appel de référence. P>
La raison pour laquelle le premier cas ne modifie pas la matrice [1] est que vous attribuez à la matrice extérieure copiée une nouvelle valeur de la matrice intérieure. P>
La ligne inférieure - A [0: 1] Renvoie une copie des données, mais les données internes ne sont pas copiées. P>
@ DLN385: La dernière phrase de cet article répond à votre question. Les données internes (dans votre cas, le numéro) n'est pas copiée, alors la modification de la modification de l'original.
La dernière phrase explique pourquoi a [0: 1] [0] [0] = 5 code> fonctionne. Mais
A [0: 1] = [[5]] code> ne modifie pas les données internes, et ne devrait pas i> travail. Je pense que cela doit être traité comme un cas particulier, comme
Oui, lorsque la statue d'affectation (c'est-à-dire que le signal "=") vient à la suite d'une référence de tranche, il s'agit d'une chose complétée à la fois que lorsque d'autres opérations sont effectuées. Pour être clair: >>> A [0: 1] = [[5]] code> est équivalent à
a .__ Settitem __ (tranche (0,1, aucun), [5]) < / code> --- tandis que
a [0: 1] [0] = 5 code> est le même que:
a .__ getItem __ (tranche (0,1, aucun) .__ Settitem __ (0 , 5) code>
Ma compréhension est la tranchée renvoie un nouvel objet. C'est-à-dire que la valeur de retour est une nouvelle liste.
Vous ne pouvez donc pas utiliser d'opérateur d'affectation pour modifier les valeurs de la liste d'origine P>
>>> a[0:1] = [[5]]
C'est correct. Tranking renvoie un nouvel objet. Il en va de même pour attribuer des clés de dictionnaires à une nouvelle variable (E.g. FOO = myDICT [bar] code>). Les modifications apportées à la SLICE attribuée ne modifient pas la référence d'origine car elles sont une copie.
Il existe trois opérations distinctes avec les indices, tous sont traduits en appels de méthode:
a [i] = b code> => a .__ settitem __ (i, b) code> li>
-
del A [i] code> => a .__ delitem __ (i) code> li>
-
a [i] code> utilisé comme expression => a .__ getItem __ (i) code> li>
ul> ici a code>, b code> et i code> sont des expressions et i code> peut contenir Objets en tranches créés à l'aide de la syntaxe de sténographie du côlon. Par exemple: p> xxx pré> donc ce qui se passe dans votre troisième exemple est-ce: p> xxx pré> devient p> Xxx pré> le premier __ getItem __ code> renvoie une copie d'une partie de la liste, mais le second __ getItem __ code> renvoie la liste réelle à l'intérieur, qui est ensuite modifiée en utilisant __ settitem __ code>. p> Votre deuxième exemple de l'autre devient p> xxx pré> donc __ settitem __ code> est en cours d'être Appelé sur la copie en tranches, laissant la liste d'origine intacte. p> p>
Question interessante. Voyons ce que dit Alex. :)