Pasando valores en Python

Cuando se pasa una colección como lista, matriz a otra función en python, ¿hace una copia de ella, o es solo un puntero?

Python pasa referencias a objetos por valor .

Python pasa referencias a objetos por valor (como Java), y todo en Python es un objeto. Esto suena simple, pero luego notará que algunos tipos de datos parecen mostrar características de paso por valor, mientras que otros parecen actuar como paso por referencia … ¿cuál es el problema?

Es importante entender los objetos mutables e inmutables. Algunos objetos, como cuerdas, tuplas y números, son inmutables. Al modificarlos dentro de una función / método se creará una nueva instancia y la instancia original fuera de la función / método no se cambiará. Otros objetos, como listas y diccionarios son mutables, lo que significa que puede cambiar el objeto en el lugar. Por lo tanto, alterar un objeto dentro de una función / método también cambiará el objeto original fuera.

La cosa es que todo el concepto de referencia / valor no encaja en Python. Python no tiene un “valor” de una variable. Python solo tiene objetos y nombres que se refieren a objetos.

Entonces cuando llamas a una función y pones un “nombre” dentro del paréntesis, así:

def func(x): # defines a function that takes an argument ... # do something here func(myname) # calling the function 

Se pasa el objeto real que señala myname , no el nombre myname . Dentro de la función se le da otro nombre ( x ) para referirse al mismo objeto pasado.

Puede modificar el objeto dentro de la función si es mutable, pero no puede cambiar a qué apunta el nombre externo . Igual que sucede cuando lo haces.

 anothername = myname 

Por lo tanto puedo responder a tu pregunta con:

es “pasar por valor” pero todos los valores son solo referencias a objetos.

Las respuestas aquí han sido útiles, pero encuentro la necesidad de exhibir esta distinción fina que no he visto cubierta, lo cual me he probado con el experimento CL posterior:

  1. Un objeto inmutable ALONE NO SE PUEDE cambiar dentro de una llamada de función. (Las respuestas hasta ahora han dicho eso …)
  2. PERO, un objeto inmutable CONTENIDO DENTRO de un objeto mutable PUEDE ser reasignado dentro de una llamada de método.

‘num’ no cambia aquí porque es un objeto Número inmutable [admite mi punto 1]:

 def incr_num(num): num += 1 num = 0 num 0 incr_num(num) num 0 

‘list [0]’ aquí también es un objeto Número inmutable.

 def incr_list(list): list[0] += 1 list = [0] list[0] 0 incr_list(list) list[0] 1 

Entonces, ¿cómo cambió ‘list [0]’, al ser un objeto numérico inmutable, (apoya mi punto 2) mientras que el objeto numérico ‘num’ del ejemplo anterior no lo hizo? El objeto de Número inmutable ‘lista [0]’ está contenido dentro de la ‘lista’ de objeto de lista mutable, mientras que ‘num’ del primer ejemplo es solo un objeto de Número no contianed.

Aunque bien intencionado, siento que la respuesta mejor calificada de @Stephen Pape (citada a continuación), y algunas otras similares, no fueron totalmente correctas (y eso me motivó a escribir esta respuesta):

Algunos objetos, como cuerdas, tuplas y números, son inmutables. Al modificarlos dentro de una función / método se creará una nueva instancia y la instancia original fuera de la función / método no se cambiará.

Mi segundo experimento de código anterior muestra un objeto Número (‘lista [0]’) que se está modificando dentro de un método, y luego la instancia original fuera de la función cambió.

Se pasa una referencia, pero si el parámetro es un objeto inmutable, modificarlo dentro del método creará una nueva instancia.

El objeto se pasa. No es una copia, sino una referencia al objeto subyacente.

También recomendaría mirar el módulo de copy :

Documentación de Python para copia.

Le ayudará a comprender los problemas subyacentes y cómo utilizarlo para realizar su propia copia en profundidad.

Por referencia:

 >>> x = [0,1,2,3] >>> def foo(x_list): x_list[0] = 1 >>> foo(x) >>> x [1, 1, 2, 3] 

Por favor déjame dar un humilde ejemplo.

 def swap(a, b): x = a print id(x) print id(a) print id(b) a = b print id(a) b = x print id(b) a[0]= '20' var1 = ['1','2','3','4'] var2 = ['5','6','7','8','9'] print id(var1) print id(var2) swap(var1, var2) print id(var1) print id(var2) print var1 print var2 

que produce el siguiente resultado

28329344 var1 28331264 var2 28329344 x 28329344 a 28331264 b Después de a = b 28331264 a después de b = x 28329344 b después del retorno 28329344 var1 28331264 var2 [‘1’, ‘2’, ‘3’, ‘4’] [’20’, ‘6’, ‘7’, ‘8’, ‘9’]

Asignación a las direcciones de memoria 28329344 28331264 var1 var2 ab x Después de a = ba Después de b = xb Después de a [0] = ’20’ [0] = ’20’ Después de devolver [‘1’, ‘2’, ‘3’, ‘4’] [’20’, ‘6’, ‘7’, ‘8’, ‘9’]