2010-01-08 6 views
4
>>> c = [1, 2, 3] 
>>> print(c, id(c)) 
[1, 2, 3] 43955984 
>>> c += c 
>>> print(c, id(c)) 
[1, 2, 3, 1, 2, 3] 43955984 
>>> del c 
>>> c = [1, 2, 3] 
>>> print(c, id(c)) 
[1, 2, 3] 44023976 
>>> c = c + c 
>>> print(c, id(c)) 
[1, 2, 3, 1, 2, 3] 26564048 

Quelle est la différence? sont + = et + ne sont pas censés être simplement du sucre syntaxique?+ et + = les opérateurs sont différents?

+1

Votre exemple montre clairement qu'ils ne le sont pas. + = est clairement ajouté à cet objet et x = a + b (même si a = b = x) créerait clairement un nouveau résultat et l'assignerait au LHS. Je pense qu'il serait contre-productif de vérifier chaque addition pour voir s'il s'agissait d'une simple addition (comme ci-dessus) et d'optimiser cela à + =. – Lazarus

+0

pourquoi la rétrogradation?J'avoue que le titre pourrait être mieux, mais la question elle-même est tout à fait valide – Kimvais

+0

cette question a quelques bonnes informations supplémentaires sur les opérations de concaténation de liste http://stackoverflow.com/questions/2022031/python-append-vs-operator-on-lists -why-do-these-give-different-results – Kimvais

Répondre

13

docs explain it very well, je pense :

__iadd__(), etc.
Ces méthodes sont appelées à mettre en œuvre les missions arithmétiques augmentée (+=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). Ces méthodes doivent tenter d'effectuer l'opération sur place (en modifiant self) et renvoyer le résultat (qui peut être, mais ne doit pas être, self). Si une méthode spécifique n'est pas définie, l'affectation augmentée revient aux méthodes normales. Par exemple, pour exécuter l'instruction x += y, où est une instance d'une classe qui a une méthode __iadd__(), x.__iadd__(y) est appelée.

+= sont conçus pour implémenter une modification sur place. en cas de simple ajout, un nouvel objet est créé et étiqueté en utilisant le nom déjà utilisé (c).

En outre, vous remarquerez qu'un tel comportement de += opérateur uniquement possible en raison de la nature mutable des listes. - Entiers un type immuable - ne produira pas le même résultat:

>>> c = 3 
>>> print(c, id(c)) 
3 505389080 
>>> c += c 
>>> print(c, id(c)) 
6 505389128 
+0

Un autre point est l'ordre d'évaluation/précédence. dans 'c = c + c' le' c + c' est évalué avant l'affectation 'c =', où comme dans 'c + = c' il n'y a pas deux opérations différentes en soi. – Kimvais

+0

c'est ce que je dis :) – SilentGhost

3

Ils ne sont pas même

c + = c ajouter une copie du contenu de c à c se

c = c + c créer un nouvel objet avec c + c

1

L'opérateur + = ajoute la deuxième liste à la première, mais la modification est en place, de sorte que l'ID reste le même. Lorsque vous utilisez +, une nouvelle liste est créée, et le "c" final est une nouvelle liste, donc il a un ID différent.

Le résultat final est le même pour les deux opérations.

2

Pour

foo = [] 

foo+=foo est le sucre syntaxique pour foo.extend(foo) (et non foo = foo + foo)

Dans le premier cas, vous êtes juste annexant membres d'une liste dans une autre (et non la création d'un nouveau).

Le id change dans le deuxième cas car une nouvelle liste est créée en ajoutant deux listes. Il est fortuit que les deux sont les mêmes et que le résultat est lié au même identifiant qu'une fois indiqué.

Si vous reformulez cette question avec des listes différentes (et non c elle-même), cela deviendra probablement plus clair.

Questions connexes