Ver índice de contenidos del libro

10.3. Mutabilidad e Inmutabilidad

Hasta ahora cada vez que estudiamos un tipo de variables indicamos si son mutables o inmutables.

Cuando una variable es de un tipo inmutable, como por ejemplo una cadena, es posible asignar un nuevo valor a esa variable, pero no es posible modificar su contenido.

>>> a="ejemplo"
>>> a="otro"
>>> a[2]="c"
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

Esto se debe a que cuando se realiza una nueva asignación, no se modifica la cadena en sí, sino que la variable a pasa a apuntar a otra cadena. En cambio, no es posible asignar un nuevo caracter en una posición, ya que esto implicaría modificar la cadena inmutable.

En el caso de los parámetros mutables, la asignación tiene el mismo comportamiento, es decir que las variables pasan a apuntar a un nuevo valor.

>>> lista1 = [10, 20, 30]
>>> lista2 = lista1
>>> lista1 = [3, 5, 7]
>>> lista1
[3, 5, 7]
>>> lista2
[10, 20, 30]

Algo importante a tener en cuenta en el caso de las variables de tipo mutable es que si hay dos o más variables que apuntan a un mismo dato, y este dato se modifica, el cambio se ve reflejado en ambas variables.

>>> lista1=[1, 2, 3]
>>> lista2 = lista1
>>> lista2[1] = 5
>>> lista1
[1, 5, 3]

Nota En otros lenguajes, como C o C++, existe un tipo de variable especial llamado puntero, que se comporta como una referencia a una variable, como es el caso de las variables mutables del ejemplo anterior.

En Python no hay punteros como los de C o C++, pero todas las variables son referencias a una porción de memoria, de modo que cuando se asigna una variable a otra, lo que se está asignando es la porción de memoria a la que refieren. Si esa porción de memoria cambia, el cambio se puede ver en todas las variables que apuntan a esa porción.

10.3.1. Parámetros mutables e inmutables

Las funciones reciben parámetros que pueden ser mutables o inmutables.

Si dentro del cuerpo de la función se modifica uno de estos parámetros para que apunte a otro valor, este cambio no se verá reflejado fuera de la función. Si, en cambio, se modifica el contenido de alguno de los parámetros mutables, este cambio se verá reflejado fuera de la función.

A continuación un ejemplo en el cual se asigna la variable recibida, a un nuevo valor. Esa asignación sólo tiene efecto dentro de la función.

>>> def no_cambia_lista(lista):
...     lista = range(len(lista))
...     print lista
...
>>> lista = [10, 20, 30, 40]
>>> no_cambia_lista(lista)
[0, 1, 2, 3]
>>> lista
> [10, 20, 30, 40]

A continuación un ejemplo en el cual se modifica la variable recibida. En este caso, los cambios realizados tienen efecto tanto dentro como fuera de la función.

>>> def cambia_lista(lista):
...     for i in range(len(lista)):
...         lista[i] = lista[i]**3
...
>>> lista = [1, 2, 3, 4]
>>> cambia_lista(lista)
>>> lista
[1, 8, 27, 64]

Advertencia En general, se espera que una función que recibe parámetros mutables, no los modifique, ya que si se los modifica se podría perder información valiosa.

En el caso en que por una decisión de diseño o especificación se modifiquen los parámetros recibi-dos, esto debe estar claramente documentado, dentro de las postcondiciones.

Copyright (c) 2011-2014 Rosita Wachenchauzer, Margarita Manterola, Maximiliano Curia, Marcos Medrano, Nicolás Paez. La copia y redistribución de esta página se permite bajo los términos de la licencia Creative Commons Atribución - Compartir Obras Derivadas Igual 3.0 siempre que se conserve esta nota de copyright.