Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

061 Mutabilidad

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 5

061 Mutabilidad

September 16, 2024

0.1 Mutabilidad
Enlace: Mutabilida
Los diferentes tipos de Python u otros objetos en general, pueden ser clasificados atendiendo a su
mutabilidad. Pueden ser:
• Mutables: Si permiten ser modificados una vez creados.
• Inmutables: Si no permiten ser modificados una vez creados.
Son mutables los siguientes tipos:
• Listas
• Bytearray
• Memoryview
• Diccionarios
• Sets
• Y clases definidas por el usuario
Y son inmutables:
• Booleanos
• Complejos
• Enteros
• Float
• Frozenset
• Cadenas
• Tuplas
• Range
• Bytes
Sabida ya la clasificación, tal vez te preguntes porqué es esto relevante. Pues bien, Python trata
de manera diferente a los tipos mutables e inmutables, y si no entiendes bien este concepto, puedes
llegar a tener comportamientos inesperados en tus programas.
La forma más sencilla de ver la diferencia, es usando las listas en oposición a las tuplas. Las
primeras son mutables, las segundas no.
Una lista l puede ser modificada una vez creada.
[7]: # La asignación se puede realizar

1
l = [1, 2, 3]
l[0] = 0
print(l)

[0, 2, 3]
Como hemos explicado antes, id() nos devuelve un identificador único del objeto. Como puedes
observar, es el mismo antes y después de realizar la modificación.
[10]: l = [1, 2, 3]

print(id(l))
l[0] = 0
print(id(l))

132136790391296
132136790391296
Sin embargo, una tupla es inmutable, por lo que la siguiente asignación dará un error.
[12]: # La asignación no se puede realizar

t = (1, 2, 3)
t[0] = 0

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[12], line 4
1 # La asignación no se puede realizar
3 t = (1, 2, 3)
----> 4 t[0] = 0

TypeError: 'tuple' object does not support item assignment

Aunque la tupla es inmutable, si que habría una forma de modificar el valor de t, pero lo que en
realidad hacemos es crear una nueva tupla y asignarle el mismo nombre. Se podría hacer algo como
lo siguiente, convertir la tupla en lista, modificar la lista y convertir a tupla otra vez.
[17]: t = (1, 2, 3)
print(id(t))
t = list(t)

# Modificar elemento
t[0] = 0

t = tuple(t)
print(t) # (0, 2, 3)
print(id(t)) # El iodentificador no cambia a pesar de los cambios realizados.

2
132135731169024
(0, 2, 3)
132135731169024
Como puedes ver, hemos conseguido modificar el valor de t, pero id(t) ya no nos devuelve el mismo
valor. El nombre de la variable es el mismo, pero el objeto al que “apunta” ha cambiado. Lo mismo
pasa con los sets (mutables) y los frozenset (no mutables). Esto no resulta tan evidente si usamos
un entero. Veamos un ejemplo. Tenemos una variable x con su id y le añadimos una unidad. El
resultado es que el identificador cambia, ya que Python no puede cambiar el 5 al ser el entero un
tipo inmutable.
[20]: x = 5
print(id(x))
x = x + 1
print(id(x)) # Ha cambiado

9761416
9761448
Sin embargo, si usamos una lista, que es un tipo mutable, al intentar modificar la x, dicha modifi-
cación puede ser realizada en la misma variable, por lo que el id() es el mismo.

[23]: x = [1, 2]
print(id(x))

x.append(3)
print(id(x)) # Id nNo cambia

132135731168896
132135731168896
Las principales diferencias entre tipos mutables e inmutables son las siguientes: * Los tipos in-
mutables son generalmente más rápidos de acceder. Por lo que si no piensas modificar una lista, es
mejor que uses una tupla. * Los tipos mutables son perfectos cuando quieres cambiar su contenido
repetidas veces. * Los tipos inmutables son caros de cambiar, ya que lo que se hace en realidad es
hacer una copia de su contenido en un nuevo objeto con las modificaciones.

0.2 Excepciones de mutabilidad


Aunque tampoco se trata de una excepción propiamente dicha ya que no rompe con lo explicado
anteriormente, hay casos en los que si podría parecer que se modifica un tipo inmutable. Imaginemos
que tenemos una tupla (inmutable) compuesta por varios elementos, donde hay una lista (mutable).

[29]: l = [4, 5, 6]

# La lista es parte de la tupla


t = (1, 2, 3, l)
print(t)

# Podemos modificar la lista

3
l[0] = 0

# Que también modifica la tupla


print(t) # (1, 2, 3, [0, 5, 6])

(1, 2, 3, [4, 5, 6])


(1, 2, 3, [0, 5, 6])
Aunque parece que hayamos modificado la tupla t, lo que en realidad hemos modificado es la lista
l, y como la tupla referencia a ella, también se ve modificada.

0.3 Mutabilidad y paso por valor/referencia


La mutabilidad de los objetos es una característica muy importante cuando tratamos con funciones,
ya que Python los tratará de manera distinta.
Si conoces lenguajes de programación como C, los conceptos de paso por valor o referencia te
resultarán familiares:
* Los tipos inmutables son pasados por valor, por lo tanto dentro de la función se accede a una
copia y no al valor original. * Los tipos mutables son pasados por referencia, como es el caso de las
listas y los diccionarios. Algo similar a como C pasa las array como punteros. Veamos un ejemplo.
Tenemos una función que modifica dos variables. Si llamamos a la función con ambas variables,
vemos como el valor de x no ha cambiado, pero el de y sí.
[7]: def funcion(a, b):
a = 10
b[0] = 10

# x es un entero
x = 5

# y es una lista
y = [5]

funcion(x, y)

print(x) # 5
print(y) # 10

5
[10]
Esto se debe a que a=10 trabaja con un valor de a local a la función, al ser el entero un tipo
inmutable. Sin embargo b[0]=10 actúa sobre la variable original.

0.4 Ejercicios y ejemplos


0.4.1 Modificar una tupla con slicing
Como hemos visto anteriormente, realizar la siguiente asignación no es posible

4
[18]: T = (1, 2, 3, 4, 5)

T = T[:2] + (0,) + T[3:]

print(T) #(1, 2, 0, 4, 5

# TypeError: 'tuple' object does not support item assignmen

(1, 2, 0, 4, 5)

[22]: T = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)


T = T[:2] + (0,) + T[4:]
print(T)

(1, 2, 0, 5, 6, 7, 8, 9, 10, 11, 12)

[ ]:

También podría gustarte