Colecciones Avanzadas en Python: UserDict, namedtuple y más
El módulo collections nos brinda un conjunto de objetos primitivos que nos permiten extender el comportamiento de las built-in collections que poseé Python y nos otorga estructuras de datos adicionales. Por ejemplo, si queremos extender el comportamiento de un diccionario, podemos extender la clase UserDict; para el caso de una lista, extendemos UserList; y para el caso de strings, utilizamos UserString.
Por ejemplo, si queremos tener el comportamiento de un diccionario podemos escribir el siguiente código:
classSecretDict(collections.UserDict): def _password_is_valid(self, password): …
def _get_item(self, key): …
def __getitem__(self, key): password, key = key.split(‘:’)if self._password_is_valid(password):return self._get_item(key)returnNonemy_secret_dict =SecretDict(...)my_secret_dict[‘some_password:some_key’] # si el password es válido, regresa el valor
Otra estructura de datos que vale la pena analizar, es namedtuple. Hasta ahora, has utilizado tuples que permiten acceder a sus valores a través de índices. Sin embargo, en ocasiones es importante poder nombrar elementos (en vez de utilizar posiciones) para acceder a valores y no queremos crear una clase ya que únicamente necesitamos un contenedor de valores y no comportamiento.
El módulo collections también nos ofrece otros primitivos que tienen la labor de facilitarnos la creación y manipulación de colecciones en Python. Por ejemplo, Counter nos permite contar de manera eficiente ocurrencias en cualquier iterable; OrderedDict nos permite crear diccionarios que poseen un orden explícito; deque nos permite crear filas (para pilas podemos utilizar la lista).
En conclusión, el módulo collections es una gran fuente de utilerías que nos permiten escribir código más “pythonico” y más eficiente.
>>>from collections import namedtuple
>>>Point=namedtuple('Point',['x','y']) # Define namedtuple
>>> p =Point(10, y=20) # Creating an object
>>> p
Point(x=10, y=20)>>> p.x+ p.y30>>> p[0]+ p[1] # Accessing the values in normal way
30>>> x, y = p # Unpacking the tuple
>>> x
10>>> y
20
Crack!
Si vienen de ruby es muy parecido a lo que puedes hacer con Struct
Me costo entender este concepto. Creo que seria más entendible si siguiran enseñando como en los videos.
Les dejo mi aporte a lo que entendi(no es todo) pero si me sirvio de mucho lo saque de otra página.
Saludos.
-:link: collections — Container datatypes
El módulo collections nos brinda un conjunto de objetos primitivos que nos permiten extender el comportamiento de las built-in collections que poseé Python y nos otorga estructuras de datos adicionales.Por ejemplo, si queremos extender el comportamiento de un diccionario, podemos extender la clase UserDict; para el caso de una lista, extendemos UserList; y para el caso de strings, utilizamos UserString.1.`namedtuple()` factory functionfor creating tuple subclasses with named fields
2.`deque` list-like container with fast appends and pops on either end
3.`ChainMap` dict-like classfor creating a single view of multiple mappings
4.`Counter` dict subclass for counting hashable objects
5.`OrderedDict` dict subclass that remembers the order entries were added
6.`defaultdict` dict subclass that calls a factory function to supply missing values
7.`UserDict` wrapper around dictionary objects for easier dict subclassing
8.`UserList` wrapper around list objects for easier list subclassing
9.`UserString` wrapper around string objects for easier string subclassing
##### Counter```python
from collections importCounter
count = defaultdict(int)names_list ="Mike John Mike Anna Mike John John Mike Mike Britney Smith Anna Smith".split()for names in names_list: count[names]+=1print(count)# Output:defaultdict(<class'int'>,{'Mike':5,'Britney':1,'John':3,'Smith':2,'Anna':2})
OrderedDict
Ordenar diccionario(s)
from collections import OrderedDict
od = OrderedDict()od['a']=1od['b']=2od['c']=3print(od)# Output:OrderedDict([('a',1),('b',2),('c',3)])
for key, value in od.items():print(key, value)# Outputa 1b 2c 3
Wowww excelente aporte, muchas gracias, no había logrado entender, pero tu lo solucionaste todo.
Buen aporte, se agradece bastante:) .
No me parece de lo más adecuado que estando viendo programación estructurada con python y se ponga de trancazo una explicación y código orientado a objetos, esto puede causar mucha confusión al momento de leerlo y más a los programadores que apenas están aprendiendo
concuerdo contigo, yo recién estoy aprendiendo y la verdad no entendí nada.
Deberian trasladar esta clase para luego de las de POO, queda mucho más claro.
No me gustó, . deberían hacer un video, sería más explicativo..
Yep, deberían explicar más afondo.
Estoy de acuerdo con eso
Este post me ayudo a entender el tema:
Módulo Collections
Muy buena la pagina!
¡Muchas gracias!
Esto hubiera estado mejor en un vídeo, y no solo un texto, la metodología que usan esta dejando mucho que desear. Meten un texto a modo de introducción y vienen clases algo que no han abordado anteriormente Mal!
Toda la razón.
Estoy de acuerdo contigo.
También cabe recalcar que: Él coloca un ejemplo en Orientación a objetos y el ni si quiera se ha tomado la molestia de explicar la sintaxis orientación a objetos en python. (Ojo no hablo de explicar la filosofía o paradigmas de la orientación a objetos, hablo de explicar la sintaxis).
Se que muchos dirán que eso lo puede investigar, por internet. Y eso es verdad, pero creo que si el va ha citar un ejemplo en orientación a objetos es preciso que el curso lo de entonces la orientación objetos en python
Creo que el curso tiene que ordenarse mejor:
A) Un poco de contexto de python
B) Orientado a funciones
Sintaxis y semantica (lo necesario, no tiene que ser todo)
Estructuras y tipos de datos. (clases prácticas con cada estructura y tipos de datos)
C) Orientación a objetos
1.sintaxis y semantica (lo necesario, no tiene que ser todo)
1.1 Declaración de clases.
1.2 Intancias de objetos.
1.3 Herencia, polimorfismo ... ente otros
2.Estructura datos (sesiones prácticas con las nuevas estructuras)
Mención de algunas librerías, (esto es para saber, cuales vamos a usar)
D)Proyecto.
Muy interesante. Cada vez me gusta más Python
Counter me pareció muy interesante, funciona genial para hacer estadística pues en tres simples pasos podemos organizar la información de los datos y crear un diccionario para guardar el valor y la moda:
No entiendo algo, y es ese parámetro self. 😦 ¿Alguien me puede explicar por favor?
La palabra reservada self se utiliza para la creación de los métodos y variables dentro de un clase y el uso de ellos dentro la misma clase. En otros lenguajes como Java se usa la palabra this.
Ejemplo:
Una clase para manejar números complejos:
Esto no queda bien claro, me perdí, y creo que es bastante avanzado, para lo que venimos aquí a aprender a programar, se me esta siendo muy difícil el curso... porque aveces el profe aplica varios temas avanzados, alguien me ayuda con este modulo?
¡Hola @thejb! Claro, dime que duda tienes ;) te dejo este link con una explicación muy buena del módulo collections, para que puedas complementar a esta clase.
Hola, es bueno contarte que hay un curso anterior a este de python, si no lo haz tomando, te recomiendo que lo tomes
No entiendo nada, qué es todo eso ?
collections es un módulo que tiene Python y permite extender las funcionalidades de los diccionarios para crear tus propios diccionarios con funcionalidades muy especificas, otro concepto que se enseña aquí son NumedTuples que es muy similar a lo que se conoce en php como array asociativo.
¡Hola @Beto92! ¿Qué es lo que no entendiste? Te dejo este link para que puedas revisar una explicación distinta a esta sobre el módulo collections
Alguien que aclare por favor el primer ejemplo.
Por que a las funciones se les pasa como parametro
(self, password)?
no deberia ser:
(self, self['password'])??
porque “password” y “key” son keys del diccionario que se la pasa como parametro a la clase al crear my_secret_dict? Y para acceder a ellas hay que usar el ['password']?
classSecretDict(collections.UserDict): def _password_is_valid(self, password): …
def _get_item(self, key): …
def __getitem__(self, key): password, key = key.split(‘:’)if self._password_is_valid(password):return self._get_item(key)returnNonemy_secret_dict =SecretDict(...)my_secret_dict[‘some_password:some_key’] # si el password es válido, regresa el valor
Fijate en la funcion getitem(), ahi esta separando la key del diccionario en dos partes por un lado lakey en si y por el otro el pasword
ejecuta getitem() donde separa el valor introducido en el diccionario en dos valores
# esta linea separa la llave introducida anterioremente 'some_password:some_key'password, key = key.split(‘:’)# password ='some _password'# key ='some_key'# y luego la verifica en'''
if self._password_is_valid(password):return self._get_item(key)
No es necesario, ya que self es una variable que conoceras mejor en la clase de POO.
Pero básicamente lo que hace es traer el contenido de cuando se inicializo el objeto.
Creo que falto más explicación para esta parte, hubiera preferido vídeos o una sección completa de este tema. Les recomiendo que entiendan POO antes de meterse a este tema.
El módulo collections en Python es un módulo integrado que proporciona varias clases de colecciones adicionales, como contadores, ordenadores, defaultdicts,UserDict, namedtuple
, etc. (Voy a dejar ejemplos como respuesta a este aporte) Estas clases de colecciones son similares a las clases de colecciones integradas, como listas, diccionarios, conjuntos, etc. pero tienen algunas características adicionales que las hacen más útiles en algunos casos específicos. Por ejemplo, un contador es una clase de colección que se utiliza para contar la frecuencia de elementos en una lista, mientras que un defaultdict es un diccionario que proporciona un valor predeterminado para una clave no existente.
.
En esta clase básicamente estamos utilizando un modulo decollections y estamos importando la clase UserDict.
Lo podemos importar así:
from collections importUserDict
En este ejemplo, utilizamos la clase UserDict para crear nuestra propia clase de diccionario llamada SecretDict. La clase SecretDict hereda los métodos y atributos de UserDict, lo que significa que tiene las mismas funciones que un diccionario normal de python:
classSecretDict(collections.UserDict):
Los UserDict son útiles para cuando se quieren crear diccionarios personalizados con funciones adicionales o para sobreescribir métodos existentes.
.
En este ejemplo sobreescribimos el modo getitem(), que es un método mágico en Python, que cuando se utiliza en una clase, permite a sus instancias utilizar los operadores [] (indexador). Digamos que x es una instancia de esta clase, entonces x[i] es aproximadamente equivalente a tipo(x).getitem(x, i).
.
El código en realidad no hace nada ni esta completo, es solo un ejemplo de como sobrescribir un método con esa clase.
.
Les dejo más ejemplos de collections en las respuestas, pero les recomiendo que estudien por ustedes el tema.
En este ejemplo, utilizamos un ordenador para crear un diccionario ordenado a partir de un diccionario normal. El ordenador utiliza la función "sorted" para ordenar las entradas del diccionario según las claves. A diferencia de los diccionarios normales, los ordenadores mantienen el orden en el que se insertan las entradas. Los ordenadores son útiles para cuando se quieren mantener las entradas en un orden especifico y no solo acceder a ellas por su valor y llave.
from collections importOrderedDict# Crear un diccionario normal
d ={'banana':3,'apple':4,'pear':1,'orange':2}# Crear un ordenador a partir del diccionario
od =OrderedDict(sorted(d.items()))# Imprimir el ordenador
print(od)# Output:OrderedDict([('apple',4),('banana',3),('orange',2),('pear',1)])
.
En este ejemplo, utilizamos un defaultdict con un valor predeterminado de 0. El defaultdict es similar a un diccionario normal, pero proporciona un valor predeterminado para las claves que no existen en el diccionario. En este caso, utilizamos la función "lambda" para definir un valor predeterminado de 0. Si accedemos a una clave no existente en el defaultdict, se devuelve el valor predeterminado en lugar de una excepción. Los defaultdicts son útiles para cuando se quieren evitar errores comunes al acceder a una clave que no existe en un diccionario.
Copy code
from collections import defaultdict
# Crear un defaultdict con un valor predeterminado de 0dd =defaultdict(lambda:0)# Añadir entradas al defaultdict
dd['a']+=1dd['b']+=2dd['c']+=3# Imprimir el defaultdict
print(dd)# Output:defaultdict(<function<lambda> at 0x...>,{'a':1,'b':2,'c':3})# Acceder a una clave no existente
print(dd['d'])# Output:0
Esta página es muy explicativa. Python Collections
Gracias!
No entiendo a que te refieres con ''Comportamiento de un diccionario"
¡Hola Mauricio! Con esto el profesor se refiere a extender las funcionalidades que tiene un diccionario normal a partir de un módulo de Python ;)
Buenísimo. Sólo un poco complejo al comienzo. Espero ir aclarando mis dudas en el camino.
¡Hola Roberto! ¿Qué es lo que no entendiste? Te dejo este link para que puedas revisar una explicación distinta a esta sobre el módulo collections
Es un poco dificil de entender el concepto, pero aca les dejo algo que me sirvio muchisimo
¡Hola @thejb! Al parecer hubo un error y no se puede ver lo que compartiste :/ ¿Podrías hacerlo de nuevo?
Me gustó mucho el Counter .... por acá les dejo algunas de las cosas que ví en el help(collections.Counter):
Saber cuales son los N elementos que más apariciones tiene en la lista con el método most_common()
Establecer un elemento en cero pero que se mantenga en la lista de elementos (asignación a cero)
import collections
my_string ='abracadabra'c = collections.Counter(my_string)print(c.most_common(3)) #returned [('a',5),('r',2),('b',2),('c',1),('d',1)]print(c['b']) #returned 2c['b']=0 #remove all 'b' but keep the element.Returned nothing
print(c)
Podrías asignarlo a una variable y con ello, posteriormente, crear un histograma y luego modelar una distribución!!