Apuntes_Python/02_conceptos/06_collections/colecciones.py
2022-12-24 22:41:20 -03:00

243 lines
6.4 KiB
Python
Executable File

"""
Collections: Estes módulo implementa un tipo de dato contenedor especializado
(specialized container datatypes) provee alternativas a los contenedores de
proposito general que vienen en el lenguaje (builted-in): dict, list, set, and tuple.
Tipos de dato contenedores, especializados:
- Counter
- namedtuple
- OrderedDict
- defaultdict
- deque
- ChainMap
- UserDict
- UserString
- 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**
"""
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()
# <itertools.chain object at 0x7fe277291400>
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.
"""
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
"""
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 []
"""
from collections import defaultdict
dd = defaultdict(int)
dd['a'] = 1
dd['b'] = 2
dd['c'] = 3
dd['d'] = 4
dd # defaultdict(<class 'int'>, {'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()
"""
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
"""
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.
"""
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.
"""
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.
"""
from collections import UserList
L = [1, 2, 3, 4]
# creación userlist
ul = UserList(L)
ul.data # [1, 2, 3, 4]