2012-07-20 16 views
35

me encontré con el hecho de que numpy matrices se pasan por referencia en múltiples lugares, pero luego cuando yo haga el siguiente código, ¿por qué hay una diferencia entre el comportamiento de foo y bar¿Las matrices numpy se pasan por referencia?

import numpy as np 

def foo(arr): 
    arr = arr - 3 

def bar(arr): 
    arr -= 3 

a = np.array([3, 4, 5]) 
foo(a) 
print a # prints [3, 4, 5] 

bar(a) 
print a # prints [0, 1, 2] 

estoy usando python 2.7 y numpy versión 1.6.1

+1

Relacionados: http://stackoverflow.com/q/9047111/166749 –

+0

Esto que Python llama "referencias" no tiene nada que ver con las referencias de paso, es por eso. – delnan

Respuesta

46

En Python, all variable names are references to values.

Cuando Python evalúa una tarea, the right-hand side is evaluated before the left-hand side. arr - 3 crea una nueva matriz; no modifica arr in situ.

arr = arr - 3 hace que la variable local arr haga referencia a esta nueva matriz. No modifica el valor referenciado originalmente por arr que se pasó a foo. El nombre de la variable arr simplemente se une a la nueva matriz, arr - 3. Además, arr es un nombre de variable local en el alcance de la función foo. Una vez que se completa la función foo, no hay más referencia a arr y Python es libre de recolectar el valor al que hace referencia. As Reti43 points out, para que el valor arr 's para afectar a, foo deben volver arr y a deberá ser asignado a ese valor:

def foo(arr): 
    arr = arr - 3 
    return arr 
    # or simply combine both lines into `return arr - 3` 

a = foo(a) 

Por el contrario, arr -= 3, que Python se traduce en una llamada a la __iadd__ special method, se modifican los la matriz a la que hace referencia el arr en contexto.

+6

que es algo así como ... – Mehdi

+0

Y por lo tanto, para que 'foo()' tenga un efecto, necesita devolver 'arr' y en el código lo ejecuta como' a = foo (a) ' . – Reti43

+0

Espera, ¿se pasan los objetos por referencia a las funciones en python ...? –

8

La primera función calcula (arr - 3), a continuación, asigna el nombre local arr a ella, que no afecta a la matriz de datos se ha pasado. Mi suposición es que en la segunda función, np.array anula el operador -=, y opera en su lugar en la matriz de datos.

Cuestiones relacionadas