7
votes

Comportement inattendu pour une division autochtone numpy

def f(x):
    x=x/5.
    return x
def g(x):
    x/=5.
    return x

x_var = np.arange(5,dtype=np.double)
f(x_var)
print x_var
g(x_var)
print x_var

Output:
[ 0.  1.  2.  3.  4.]
[ 0.   0.2  0.4  0.6  0.8]
This behavior is a little bit strange to me, I always thought x/=5. was equivalent to x=x/5. . But clearly the g(x) function does not create a new reference with /= operation.  Could anyone offer an explanation for this?

0 commentaires

3 Réponses :


7
votes

J'ai toujours pensé x / = 5. était équivalent à x = x / 5

C'est, à moins que la classe remplace l'opérateur __ idiv __ , comme numpy.ndarray fait. Numpy.ndarray le remplace pour modifier la matrice en place, ce qui est bon car il évite de créer une nouvelle copie du tableau, lors de la copie n'est pas requise. Comme vous pouvez le deviner, il remplace également le reste des opérateurs __ i * __ .


3 commentaires

Merci pour l'explication, je n'ai pas pu trouver la documentation qui me conduirait à m'attendre à ce comportement.


Ce n'est pas un problème engourdi, c'est un problème de passage par problème de référence. La mise en œuvre par défaut de tous les __ i * __ est de faire le fonctionnement en place si possible, lisez le DOCS . Vous aurez le même problème à passer une liste de python à une fonction def F (a): A * = 3; Renvoie un , il modifierait l'objet d'origine que vous avez appelé avec, non seulement renvoyer une copie modifiée.


Merci, c'était la référence de la documentation que je cherchais. Cela devrait donc effectuer l'opération en place si possible. Si le I * n'est pas disponible, il sera par défaut à l'opération normale * .



3
votes

Les opérateurs en place de Python permettent à l'opération de modifier l'objet sur le côté gauche de l'équation plutôt que de créer un nouveau. Vous verrez le même comportement avec la liste S et d'autres types mutables intégrés: xxx

donc cela est donc le comportement attendu.

quand Traiter avec des types immuables, bien sûr, un nouvel objet est créé, car celui-ci ne peut pas être modifié.


0 commentaires

0
votes

J'ai toujours pensé x / = 5. était équivalent à x = x / 5.

Ce n'est pas le cas. Lorsque vous faites x = x / 5. , vous effectuez des opérations deux opérations distinctes sous la hotte: xxx < P> Alors que lorsque vous utilisez l'opérateur / = , vous demandez explicitement Python de modifier votre objet x en place, sans création d'un objet temporaire. Comme mentionné dans d'autres réponses, l'opérateur / méthode de votre objet (le cas échéant), tandis que / = appelle son __IVIV __ Méthode.

La modification en place est assez utile si l'objet que vous modifiez est grand: pas besoin de créer un objet temporaire aussi grand. Cependant, cela peut vous mordre si vous n'êtes pas prudent. En particulier, ce n'est généralement pas si grande une idée d'avoir une fonction modifier ses paramètres d'entrée sans avertissement ...


0 commentaires