# Modulo collections Collections: Estes módulo implementa un tipo de dato contenedor especializado (specialized container datatypes). Provee alternativas al los contenedores de proposito general que vienen en el lenguaje (built-in): * dict * list * set * tuple Tipos de dato contenedores, especializados: - [Counter](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#counter) - [namedtuple](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#namedtuple) - [OrderedDict](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#ordereddict) - [defaultdict](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#defaultdict) - [deque](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#deque) - [ChainMap](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#chainmap) - [UserDict](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#userdict) - [UserString](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#userstring) - [UserList](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/06_collections#userlist) ## Counter Contenedor que almacena los elementos como llaves de diccionario, y su cuenta, como valores del diccionario. **subclase de diccionario usada para contar objects hashables** ```python from collections import Counter a = 'aaaaabbbbccc' # crear contador mi_contador = Counter(a) # Counter({'a': 5, 'b': 4, 'c': 3}) # itemms() mi_contador.items() # dict_items([('a', 5), ('b', 4), ('c', 3)]) # keys() mi_contador.keys() # dict_keys(['a', 'b', 'c']) # values() mi_contador.values() # dict_values([5, 4, 3]) # most_common() # retorna lista con tuplas de el o los elementos mas cómunes mi_contador.most_common(2) # [('a', 5), ('b', 4)] # acceder al elemento de la tupla mi_contador.most_common(1)[0][0] # a # elements(), devuelve un objeto iterable mi_contador.elements() # list(mi_contador.elements()) # ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c'] ``` ## namedtuple() Retorna una tupla con nombre de entrada, los que significa que se asignará un nombre a cada valor en la tupla. Esto soluciona el problema de acceder elementos usando indices. con namedtuple( ) se vuelve mas fácil acceder a estos valores, ya que no se deben recordar los indices para obtener elementos específicos. ```python from collections import namedtuple Punto = namedtuple('Punto', 'x,y') pt = Punto(4, -1) # Punto(x=4, y=-1) pt.x # 4 pt.y # -1 cursos = namedtuple('cursos' , 'nombre , tecnología') curso_a = cursos('data science' , 'python') # cursos(nombre='data science', tecnología='python') curso_a.nombre # 'data science' curso_a.tecnología # 'python' # crear namedtuple usando una lista curso_a._make(['data science', 'python']) # cursos(nombre='data science', tecnología='python') ``` ## OrderedDict Subclase dict que recuerda el orden de las entradas agregadas. Aunque se cambie el valor de una llave la posición de esta no cambia. * desde pyton 3.7 los diccionarios por defecto recuerdan el orden lo que vuelve irrelevante este objeto tipo ```python from collections import OrderedDict od = OrderedDict() od['a'] = 1 od['b'] = 2 od['c'] = 3 od['d'] = 4 od['e'] = 5 od # OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]) ``` ## defaultdict Subclase dict que llama una funcion factory para suplir valores faltantes. En general, no arroja errorres por algun valor de llave faltante al llamar a un diccionario. `defaultdict(int)` devuelve 0, en vez de KeyError `defaultdict(float)` devuelve 0.0 `defaultdict(list)` devuelve [] ```python from collections import defaultdict dd = defaultdict(int) dd['a'] = 1 dd['b'] = 2 dd['c'] = 3 dd['d'] = 4 dd # defaultdict(, {'a': 1, 'b': 2, 'c': 3, 'd': 4}) dd['b'] # 2 dd[6] # 0 ``` ## deque Contenedor similar a la lista, con appends mas rápidos, y pops en ambos extremos. metodos: * append() * appendleft() * pop() * popleft() * clear() * extend() * extendleft() * rotate() ```python from collections import deque d = deque() d.append(1) d.append(2) d # deque([1,2]) d.appendleft(3) d # deque([3, 1, 2]) d.pop() # 2 d # deque([3, 1]) d.popleft() # 3 d # deque([1]) d.clear() # deque([]) d.extend([1, 2, 3, 4]) # deque([1, 2, 3, 4]) d.extendleft([5, 6, 7, 8]) # deque([8, 7, 6, 5, 1, 2, 3, 4]) # rotar a la derecha (2 lugares) d.rotate(2) # deque([3, 4, 8, 7, 6, 5, 1, 2]) # rotar a la izquierda (1 lugar) d.rotate(-1) # deque([4, 8, 7, 6, 5, 1, 2, 3]) ``` ## ChainMap Es una clase similar a un diccionario que puede hacer una sola vista de múltiples asignaciones. Básicamente, devuelve una lista de varios otros diccionarios. Suponiendo que tiene dos diccionarios con varios pares clave-valor, en este caso ChainMap creará una lista única con ambos diccionarios en ella. metodos: * clear * fromkeys * items * maps * parents * popitem * update * copy * get * keys * new_child * pop * setdefault * values ```python from collections import ChainMap d1 = {'a': 1, 'b': 2} d2 = {'c': 3, 'd': 4} cm = ChainMap(d1, d2) cm # ChainMap({'a': 1, 'b': 2}, {'c': 3, 'd': 4}) ``` ## UserDict Esta clase actúa como un envoltorio al rededor de un diccionario. Simula un diccionario. El contenido de la instancia se mantiene en un diccionario regular que puede ser accedido con el atributo 'data' de la clase UserDict. La referencia de los datos originales no es mantenida, y puede ser utilizarse para otros propositos. ```python from collections import UserDict d = {'a':1, 'b': 2, 'c': 3} # Creación ud = UserDict(d) ud # {'a': 1, 'b': 2, 'c': 3} ``` ## UserString Similar a UserDict y UserList, actúa como envoltorio alrededor de objetos string. Usado cuando se requiere crear subclases de string con funcionalidad modificada o añadida. ```python from collections import UserString d = 12344 # creación us = UserString(d) us # '12344' class Mistring(UserString): "creación de string mutable" def append(self, s): "function append to string" self.data += s def remove(self, s): "Función para remover desde el string " self.data = self.data.replace(s, "") us1 = Mistring("Pruebas") us1.data # 'Pruebas' # agregar a string us1.append("s") us1.data # 'Pruebass' # remover del string us1.remove("e") us1.data # 'Pruebas' ``` ## UserList Actua como envoltorio alrededor de una lista. Útil como clase base para otros objetos similares a listas que pueden hereder desde estas y sobrescribir los metodos existentes o incluso agregar propios. Esta clase existe para facilitar la creacion de subclases directamente desde una lista. Facilita el trabajar con esta clase ya que la lista pasada se vuelve atributo. ```python from collections import UserList L = [1, 2, 3, 4] # creación userlist ul = UserList(L) ul.data # [1, 2, 3, 4] ```