7
votes

Attribuer une valeur à un élément d'une tranche en python

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> xxx pré>

Exemple 2: strong> p>

>>> a = [[1], 2]
>>> a[0:1][0][0]
1
>>> a[0:1][0][0] = 5
>>> a
[[5], 2] # Why now?


1 commentaires

Question interessante. Voyons ce que dit Alex. :)


3 Réponses :


7
votes

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.

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.

La ligne inférieure - A [0: 1] Renvoie une copie des données, mais les données internes ne sont pas copiées.


3 commentaires

@ 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 fonctionne. Mais A [0: 1] = [[5]] ne modifie pas les données internes, et ne devrait pas travail. Je pense que cela doit être traité comme un cas particulier, comme Pyfunc semble impliquer.


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]] est équivalent à a .__ Settitem __ (tranche (0,1, aucun), [5]) < / code> --- tandis que a [0: 1] [0] = 5 est le même que: a .__ getItem __ (tranche (0,1, aucun) .__ Settitem __ (0 , 5)



3
votes

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]]


1 commentaires

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] ). Les modifications apportées à la SLICE attribuée ne modifient pas la référence d'origine car elles sont une copie.



1
votes

Il existe trois opérations distinctes avec les indices, tous sont traduits en appels de méthode:

  • a [i] = b => a .__ settitem __ (i, b)
  • del A [i] => a .__ delitem __ (i)
  • a [i] utilisé comme expression => a .__ getItem __ (i)

    ici a , b et i sont des expressions et i peut contenir Objets en tranches créés à l'aide de la syntaxe de sténographie du côlon. Par exemple: xxx

    donc ce qui se passe dans votre troisième exemple est-ce: xxx

    devient Xxx

    le premier __ getItem __ renvoie une copie d'une partie de la liste, mais le second __ getItem __ renvoie la liste réelle à l'intérieur, qui est ensuite modifiée en utilisant __ settitem __ .

    Votre deuxième exemple de l'autre devient xxx

    donc __ settitem __ est en cours d'être Appelé sur la copie en tranches, laissant la liste d'origine intacte.


0 commentaires