Estaría interesante tener una inmersión mayor de estos terminos (inmutabilidad, mutabilidad) dentro de la POO. 🤖
Introducción
El Zen de Python
Conjuntos
Sets
Modificando conjuntos
Operaciones con conjuntos
Playgrounds: Elimina elementos duplicados usando conjuntos
Comprehensions
List Comprehension
Dictionary Comprehension
Dictionary Comprehension: condition
Playgrounds: Crea una lista usando List Comprehension
Lists vs. Tuples vs. Sets
Funciones
Funciones
Funciones: return
Parámetros por defecto y múltiples returns
El scope
Refactor game
Playgrounds: Tienda de Tecnología
Funciones anónimas: lambda
Higher order function: una función dentro de otra función
Map
Map con diccionarios
Reto: map con inmutabilidad
Playgrounds: Multiplica todos los elementos por dos
Filter
Playgrounds: Retorna solo palabras de 4 letras y más
Reduce
Módulos
Módulos
Mis propios módulos
Módulos como scripts: __name__ y __main__
Paquetes
Playgrounds: Calcular la suma de todas las compras
Manipulación de archivos y errores
Iterables
Errores en Python
Manejo de excepciones
Playgrounds: Captura la excepción: ZeroDivisionError
Leer un archivo de texto
Escribir en un archivo
Leer un CSV
Playgrounds: Lee un CSV para calcular el total de gastos
Gráficas en Python
Creando una gráfica
Reto: graficando la población de un país
Reto: graficando la población mundial
Próximos pasos
¡Conoce otros proyectos de este curso!
Reconoce tu proceso y certifícate
Toma el Curso de PIP y Entornos Virtuales con Python
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 94
Preguntas 14
Estaría interesante tener una inmersión mayor de estos terminos (inmutabilidad, mutabilidad) dentro de la POO. 🤖
Me gustaría que este docente se ocupe de toda la ruta de backend con Python ¿Les gusta la idea?
Vamos Platzi por ese curso de mutabilidad e inmutabilidad.
Realmente me parece confuso que utilice nombres muy similares, creo que no es lo mas adecuado para un curso basico pues se pueden confundir los conceptos. A lo que me refiero es que uso items, item, new item, new items. Quizá se deberia explicar un poco mejor a que se refiere cada uno de estos
lo que acaba de hacer en este curso a esa función se le llama: Funciones puras
tiene como objetivo no crear efectos secundarios creando una copia del input, modificando y luego retornando esta copia modificada
Con base en el video que compartió un compañero: How variables work in Python | Explained with Animations
En Python, no se asigna un tipo de dato a una variable, en su lugar, todo es un objeto.
Cuando se asigna un valor a una variable, un nuevo objeto es creado en memoria. Un PyObject representa la estructura base de todos los objetos de Python, conteniendo:
Estos objetos no se mueven en memoria, por lo que tienen un tamaño fijo y una dirección en memoria.
Con esto el mente, el tipo de dato no se asocia a la variable sino que es información almacenada en el objeto, es por ello que es posible almacenar diferente tipo de información en cada variable, haciendo de Python un lenguaje de tipado dinámico.
Ahora bien, es importante resaltar lo siguiente:
Se llamarán así a los objetos cuyo estado interno no se puede modificar una vez se han creado, como los números o los Strings.
Para variables de tipo contenedor, como listas o diccionarios. Estos pueden almacenar diversos valores y su estado interno puede ser modificado al almacenar o eliminar elementos.
Para este tipo de variables, en lugar de un PyObject se tiene un PyVarObject, el cual es un PyObject con un campo adicional para el tamaño, que tiene la cantidad de elementos almacenados en el objeto contenedor.
Se tiene, entonces:
también sería bueno una escuela de programación para niños dentro de platzi
tambien pueden usar la funcion copy.deepcopy(‘lista que se quiere copiar’) del archivo copy que copia todos los objetos que guarda nuestra lista (no es necesario que se guarde en ninguna variable si se envia como parametro) de esta manera nuestra lista original queda inmutable y tenemos una copya de esta con los cambios que generamos
import copy
items = [
{
'product':'remera',
'price':100,
},
{
'product':'pantalon',
'price':300,
},
{
'product':'pantalon 2',
'price':200,
},
]
def add_campo_sum( item):
item['taxes'] = item['price'] * .19
return item
print(items)
price = list(map(lambda item: item['price'], items))
print(price)
new_item = list(map(add_campo_sum,copy.deepcopy(items)))
print(f'Lista vieja \n{items}')
print(f'Lista nueva \n{new_item}')
Habiendo estudiado punteros en C en la universidad hizo mucho más fácil esta lección. Supongo que si alguien no entendió muy bien puede buscar una clase teórica en youtube acerca de posiciones de memoria, punteros y parametros por copia y referencia.
Objetos mutables vs inmutables en Python
Todo en Python es un objeto. Y lo que todo recién llegado a Python debería aprender rápidamente es que todos los objetos en Python pueden ser mutables o inmutables .
si, sería bueno un curso para profundizar exclusivamente sobre este tema de inmutabilidad
Recomiendo el siguiente vídeo:
How variables work in Python | Explained with Animations
Explica como funciona la referencia al momento de asignar listas.
El problema de la modificacion de la lista original tras aplicar una transformacion con un map se debe a la referencia en memoria, es decir, cuando trabajamos con un diccionarios hay un espacio en memoria reservada para ese diccionario; al aplicar una transformacion sobre el diccionario, los nuevos valores se asignan al diccionario como una referencia en memoria; entonces al hacer una modificacion se aplica tanto para el array original como para el nuevo ya que ambos comparten la misma referencia en memoria.
Solucion con el metodo copy()
#-------------Quitar la referencia en memoria del diccionario------------------
items = [
{
'product':'camisa',
'price':100
},
{
'product':'pantalon',
'price':300
},
{
'product':'vestido',
'price':150
},
{
'product':'chaqueta',
'price':400
}
]
# al agregar el metodo copy desreferenciamos el array original con el nuevo
def add_taxes(items):
new_item = items.copy()
new_item['taxes'] = new_item['price'] * .19
return new_item
new_items = list(map(add_taxes, items))
print('New list')
print(new_items)
--> New list
[{'product': 'camisa', 'price': 100, 'taxes': 19.0},
{'product': 'pantalon', 'price': 300, 'taxes': 57.0},
{'product': 'vestido', 'price': 150, 'taxes': 28.5},
{'product': 'chaqueta', 'price': 400, 'taxes': 76.0}]
print('Old list')
print(items)
--> Old list
[{'product': 'camisa', 'price': 100},
{'product': 'pantalon', 'price': 300},
{'product': 'vestido', 'price': 150},
{'product': 'chaqueta', 'price': 400}]
Si, deinitivamente un curso exclusivo de mutabilidad e inmutabilidad sería genial!!
items = [
{
'product':'camisa',
'price': 100,
},
{
'product':'pantalones',
'price':300
},
{
'product':'jeans',
'price':200
}
]
def add_taxes(item):
new_item = item.copy()
new_item['taxes'] = new_item['price'] * 0.19
return new_item
new_items = list(map(add_taxes, items))
print('New list')
print(new_items)
print('Old list')
print(items)
# Lista original de diccionarios
items = [
{'product':'camisa', 'price':100},
{'product':'pantalón','price':200},
{'product':'zapato', 'price':300}
]
# Función que agrega la clave 'tax' a un diccionario y devuelve un nuevo diccionario
def add_tax(item):
return {**item, 'tax': item['price'] * 0.19}
# Utilizar map para aplicar la función a cada elemento de la lista
new_items = list(map(add_tax, items))
# Imprimir la lista original y la nueva lista
print("Original:\n", items)
print()
print("Con 'tax':\n", new_items)
El diccionario comparte el mismo espacio de memoria por lo que una modificación no crea un nuevo espacio de memoria y la almacena en la misma.
Esta es otra manera, que igual cumple con la regla de inmutabilidad:
items = [
{
'product': 'shirt',
'price': 100
},
{
'product': 'pants',
'price': 250
},
{
'product': 'shorts',
'price': 30
}
]
new_items = list(map(lambda item: item | {'taxes': item['price'] * .19}, items))
print(new_items)
print(items)
yo digo que no lo piensen y vamos por ese curso de mutabilidad e inmutabilidad ya que debe haber muchos ejemplos complejos que posiblemente existan y nos ayudará a dominar mejor el lenguaje frente a trabajos futuros.
Apoyo el curso de mutabilidad e inmutabilidad uwu
sii porfavor!!! un curso de mutabilidad e inmutabilidad.
Un poco de crítica, porque cuando dicen “cuéntanos en los comentarios si quieres un curso de X cosa”, entendemos que promuevan la participación para generar comunidad, pero si creen que un curso es necesario e importante pues lo hacen, todos estamos acá para aprender.
import os
os.system('clear') # Limpiar pantalla en Unix (Windows -> 'cls')
# Lista original de diccionario
items_sin_tax = [
{'product':'camisa' , 'price':100},
{'product':'pantalón' , 'price':200},
{'product':'zapato' , 'price':300}
]
otros_items_sin_tax = [
{'product':'heladera' , 'price':150},
{'product':'lavarropas' , 'price':250},
{'product':'microondas' , 'price':350}
]
# Función que agrega la clave 'tax' a un nuevo diccionario
def add_taxes(original_list):
auxiliar_list = original_list.copy()
auxiliar_list['tax'] = auxiliar_list['price'] * 0.19
return auxiliar_list
# Lista de diccionario con impuestos
items_con_tax = list(map(add_taxes, items_sin_tax))
otros_items_con_tax = list(map(add_taxes, otros_items_sin_tax))
# Imprimir
print('ITEMS SIN TAX:' , '\n' , items_sin_tax ,'\n')
print('ITEMS CON TAX:' , '\n' , items_con_tax ,'\n')
print('OTROS ITEMS SIN TAX:' , '\n' , otros_items_sin_tax ,'\n')
print('OTROS ITEMS CON TAX:' , '\n' , otros_items_con_tax)
Esta fue la manera en que resolvi el reto.
# Importa el módulo 'copy' para realizar copias profundas de los diccionarios.
import copy
# Crea una lista de diccionarios llamada 'items' con información de productos y precios.
items = [
{
'product': 'camisa',
'price': 100,
},
{
'product': 'pantalones',
'price': 300
},
{
'product': 'pantalones 2',
'price': 200
}
]
# Muestra la lista de productos y sus precios originales.
print("Lista de productos:")
print(items)
# Calcula los precios y almacena los resultados en una nueva lista llamada 'prices'.
prices = list(map(lambda item: item['price'], items))
print("Lista de precios:")
print(prices)
# Definición de una función 'add_taxes' que agrega un campo 'taxes' a cada elemento.
def add_taxes(item):
# Realiza una copia profunda del diccionario original para no modificarlo.
item_copy = copy.deepcopy(item)
# Calcula los impuestos (19% del precio) y agrega el resultado al diccionario copiado.
item_copy['taxes'] = item_copy['price'] * 0.19
return item_copy
# Aplica la función 'add_taxes' a cada elemento de la lista 'items' y almacena los resultados en 'new_items'.
new_items = list(map(add_taxes, items))
# Muestra la lista de productos con los impuestos agregados.
print("Lista de productos con impuestos:")
print(new_items)
# Muestra la lista de productos original nuevamente.
print("Lista de productos original:")
print(items)
Interesante que un solo codigo permite no alterar el diccionario original y trabajar con el es interesante.
# Reto: map con inmutabilidad
items = [
{
'product': 'camisa',
'price': 100,
},
{
'product': 'pantalones',
'price': 300
},
{
'product': 'pantalones 2',
'price': 200
}
]
def add_taxes(item):
new_item = item.copy() #Se crea una "copia" de los valores sin afectar la referencia en memoria
new_item['taxes'] = new_item['price'] * .19
return new_item
new_items = list(map(add_taxes, items))
print('New list')
print(new_items)
print('Old list')
print(items)
Si queremos un curso de mutable and inmutable 😃
Me apunto a la idea de un curso sobre mutabilidad e inmutabilidad!
Un curso sobre mutabilidad e inmutabilidad en lenguajes de programación es importante por las siguientes razones:
Proporciona una comprensión fundamental de los conceptos de mutabilidad e inmutabilidad. Este conocimiento es esencial para poder tomar decisiones informadas sobre el uso de estos conceptos en el desarrollo de software.
Enseña las ventajas y desventajas de la mutabilidad y la inmutabilidad. Esto permite a los desarrolladores elegir el enfoque adecuado para sus necesidades.
Ayuda a los desarrolladores a escribir código más seguro y fácil de depurar. Los objetos inmutables son más seguros porque son menos propensos a causar problemas de concurrencia. También son más fáciles de depurar porque los cambios en los datos no afectan al código que los utiliza.
¿POR QUÉ SE MODIFICAN LOS DICCIONARIOS EN UNA LISTA AL UTILIZAR LA FUNCCIÓN map()?
La razón por la cual los diccionarios en la lista original se modifican cuando se aplica map() se debe a cómo funcionan los objetos mutables en Python y cómo se manejan las referencias a objetos en memoria.
Cuando trabajas con objetos mutables como los diccionarios, estás manipulando referencias a esos objetos en lugar de copiar los objetos en sí. Esto significa que cuando pasas un objeto mutable a una función y lo modificas dentro de esa función, estás modificando la referencia al objeto en memoria, no estás creando una copia independiente del objeto.
Cuando aplicas map() a una lista de diccionarios y modifica esos diccionarios dentro de la función proporcionada a map(), los cambios se reflejarán en los diccionarios originales en la lista. Esto se debe a que los diccionarios en la lista y los diccionarios dentro de la función son referencias al mismo objeto en memoria.
Si deseas evitar que los cambios afecten a los diccionarios originales en la lista, debes crear copias de esos diccionarios antes de modificarlos dentro de la función:
# CACLULAMOS EL ÁREA DE LOS RECTANGULOS y lo agregamos como nuevo atributo sin modificar los diccionarios originales.
rectangulos = [
{'longitud': 5, 'ancho': 4},
{'longitud': 3, 'ancho': 6},
{'longitud': 7, 'ancho': 2}
]
# Definimos una funcion para calcular el área y crear un nuevo diccionario
def calcular_area(rectangulo):
new_rectangulo = rectangulo.copy()# Crear una copia del diccionario original
new_rectangulo['area'] = new_rectangulo['longitud'] * new_rectangulo['ancho']
return new_rectangulo
# Utilizar map para aplicar la función calcular_area a cada rectángulo
rangulos_con_areas = list(map(calcular_area, rectangulos))
# Imprimir la lista de rectángulos con áreas calculadas
print(rangulos_con_areas)
# La lista original 'rectangulos' no se modifica
print(rectangulos)
items = [
{
" producto " : " camisa " ,
" precio " : 80000 ,
},
{
" producto " : " pantalon " ,
" precio " : 110000
},
{
" producto " : " zapatos " ,
" precio " : 200000
}
]
print(type(items))
productos = list ( map ( lambda item: item [" producto " ] , items ) )
print(productos)
precios = list ( map ( lambda item: item [" precio " ] , items ) )
print(precios)
def impuesto (item):
nuevo_item = item.copy()
nuevo_item[ " impuesto " ] = nuevo_item [ " precio " ] * .19
return nuevo_item
nuevos_itemss = list(map( impuesto , items ))
print (nuevos_itemss)
print (items)
Creo que se podria reforzar mas el tema del manejo de documentacion.
Necesitamos que platzi publique el curso de inmutabilidad, mutabilidad es muy importante para la generación de código.
En la POO hay dos formas de pasar datos:
La función ‘map’ envía a ‘add_taxes’ el valor del objeto iterado por referencia, es decir, envía realmente la dirección de memoria, ej: 0x10eba. Por ello es necesario hacer una copia para que el nuevo elemento tenga una dirección de memoria distinta y así no se altere el elemento original.
estaría bien si todos los nombres de las funciones y variables entren solo en español , porque en ingles me parece confuso apenas voy aprendiendo
Y el curso quedará en sueños ? 😅
Me encantaria un curso de ese tema
Acabo de notar que el map es similar a usar un apply. Ahora a ponerlo en práctica
items = [
{
'product': 'camisa',
'price': 100
},
{
'product': 'pantalones',
'price': 200
},
{
'product': 'joggers',
'price': 348
},
]
# cuando se modifica un diccionario puede que se esté modificando todo el array original y no uno nuevo
prices = list(map(lambda item: item['price'], items))
print(items)
print(prices)
def add_taxes(item):
new_item = item.copy()
new_item['taxes'] = new_item['price'] * .19
return new_item
new_items = list(map(add_taxes, items))
print(new_items)
print(items)
Me gusta que el curso se mantenga enfocado al objetivo.
A futuro si me gustaría saber mas sobre mutabilidad e inmutabilidad. ojalá haya un curso al respecto.
Cualquier tema que mejore mi conocimiento en python es bienvenido
Me sumo al apoyo por el curso de mutabilidad e inmutabilidad y el curso de POO en Python 🙌
A la hora de trabajar con redes neuronales es muy importante y una buena práctica usar funciones puras o inmutables. Muy buen video, ¡Saludos!
Sigo esperando los cursos prometidos, tanto este como el anterior! No veo fecha hasta el momento.
Les comparto el código de la clase con la explicación de la referencia en memoria dada por Nico!
Realmente me resultó algo confuso, pero me queda claro que esta situación solo se presenta con los diccionarios.
Seguro en las próximas clases todo pueda verse más familiar y más claro.
# Reto: map con inmutabilidad
'''
Map es una de las funciones que se considera que no modifica el estado del array original, por el contrario, crea uno nuevo.
Sin embargo, aqui se evidencia una modificacion en el array, que tiene que ver con una referencia en memoria.
¿Por qué ocurre?
Cuando trabajamos con un diccionario, hay una referencia, es decir un espacio en nuestra computadora, que tiene este diccionario.
Cuando hacemos operaciones con numeros primitivos, es decir un array de numeros, un array de strings y hacemos transformaciones, allí lo que hacemos es que en esa transformacion se está calculando un nuevo valor, por ejemplo multiplicarlo por 2, y ese valor es asignado al array. Pero cuando trabajamos con diccionarios, no se asigna como un nuevo valor, el diccionario se asigna como una referencia en memoria, entonces al hacer una modificacion, se hace una modificación tanto para el array original como para el nuevo. Estamos modificando los dos array, porque los dos comparten la misma referencia en memoria.
¿Como hago para poder sacar esa referencia en memoria?
Creamos una copia del diccionario original, haciendo uso de la funcion copy. Esto copia todos los valores de ese diccionario, pero no se trae esa referencia.
'''
# Lista de diccionarios
items = [
{
'product': 'camisa',
'price': 100
},
{
'product': 'pantalones',
'price': 300
},
{
'product': 'chaqueta',
'price': 600
}
]
# Agregamos un nuevo atributo al diccionario
def add_taxes(item):
new_item = item.copy()
new_item['taxes'] = new_item['price'] * .19
return new_item
new_items = list(map(add_taxes, items))
print("New list")
print(new_items)
print("Old list!")
print(items)
Lo mismo sucede con los Dataframes usando la libreria pandas, si no quieres modificar el dataframe original es mejor hacer una copia del mismo
Ahhhhhh ya entiendo por que me pasaba lo que me pasaba, gracias
Este video me recordó a los punteros en C, donde envías una dirección de memoria y no el valor, sin embargo, no dominé ese tema =S
Sí, también quiero el curso de (in)mutabilidad.
Si por favor un curso de mutabilidad y de inmutabilidad. Por favor.
Creo que esta perfecta tu manera de explicarlo…
Apoyo la idea del curso de inmutabilidad y mutabilidad.
La función copy solo nos funciona para niveles superficiales, sin embargo cuando tenemos variables listas dentro de listas, estas listas internas se se modifican dentro la original, una recomendación es
import copy y llamar el método deepcopy(), este si copia todas esas estructuras internas de las variables.
Si seria interesante y útil un curso de mutabilidad e inmutabilidad en Python.
Platzi si me gustaría profundizar en los conceptos de mutabilidad e inmutabilidad 😄
Si si, hagan ese curso de inmutabilidad, mutabilidad, y tal vez de otros conceptos técnicos sobre programación, porque esos temas me confunden un poco.
El metodo .copy() de python me recuerda mucho al spread operator de javascript “…” Muy buena clase a ser verdad!
Yo lo hice así:
items = [
{
'product': 'camisa',
'price': 100,
},
{
'product': 'pantalon',
'price': 200,
},
{
'product': 'Tenis',
'price': 300,
},
]
map_obj = lambda obj : {
'product': obj['product'],
'price': obj['price'],
'taxes': obj['price'] * .19,
}
items2 = list(map(map_obj, items))
print('New')
print(items2)
print('Old')
print(items)
Saludos
a mi no me funciono el utilicera el copy para cambiar la old list con la nueva
Deberias hacer el curso de POO de python el otro profe no es tan Pro como t’u, un fuerte abrazo
Me gusta la idea de un curso en los temas de mutabilidad e inmutabilidad.
y si porfavor, todo lo q sea nuevo y de valor hagamoslo nomas jajaja xD
Si Platzi…Curso de mutabilidad e inmutabilidad dicatado por Nicolás!
Me encantaria un curso de inmutabilidad, seria muy interesante profundizar sobre ese tema.
Seria de mucha ayuda profundizar mas en estas situaciones de inmutabilidad
vamos por ese curso de inmutabilidad y mutabilidad
Ya ha quedado!
vamos con ese curso de mutabilidad e inmutabilidad!
también sería muy bueno un curso sobre el tema de los xml, debido a que hoy por hoy están usando para los temas de facturación electrónica en varios países.
en mi caso particular tengo la necesidad de leer y montar bases de datos con los xml de la DIAN colombia.
Me encantó
items = [
{
'product':'laptop',
'price': 200
},
{
'product':'mouse',
'price': 15
},
{
'product':'camera',
'price': 55
},
{
'product':'headphones',
'price': 15
}
]
price = list(map(lambda items: items['price'], items))
print(price)
def taxes_item(items):
new_items = items.copy()
new_items['taxes'] = items['price'] * .22
new_items['full_price'] = items['price'] + new_items['taxes']
return new_items
taxes = list(map(taxes_item, items))
print('Old Dic')
print(items)
print('New Dic')
print(taxes)
<items = [
{
'product': 'camisa',
'price': 100,
},
{
'product': 'pantalones',
'price': 300
},
{
'product': 'pantalones 2',
'price': 200
}
]
def add_taxes(item):
new_item = item.copy()
new_item['taxes'] = new_item['price'] * .19
return new_item
new_items = list(map(add_taxes, items))
print('New list')
print(new_items)
print('Old list')
print(items)>
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?