lunes, 13 de abril de 2015

Counter, el contador de Python



El módulo collections provee nuevos tipos de datos mejorados que derivan, según el caso, de una lista, una tupla, un diccionario o conjunto de datos (set). En este artículo vamos a estudiar el objeto Counter.

Un objeto Counter es un contenedor del módulo collections que se utiliza para contar las veces que aparece un valor en una secuencia de caracteres, en una lista, un diccionario o una lista de nombres de argumentos con asignaciones. Este tipo de objeto es de una subclase que está basada en la clase dict (diccionario).

A continuación, se muestran distintas formas de construir objetos Counter y se realizan algunas operaciones que demuestran su afinidad con la clase dict.

import collections
lista1 = ['Granada', 'Huelva', 'Sevilla', 'Granada', 
          'Granada', 'Sevilla', 'Sevilla']

# Crear un objeto Counter a partir de la lista lista1
cuenta1 = collections.Counter(lista1)

# En el objeto Counter las claves son los 
# elementos (sin repetir) de la lista y los valores el
# número de veces que aparece cada elemento en la lista.
print(cuenta1)
# Counter({'Granada': 3, 'Sevilla': 3, 'Huelva': 1})

lista1.append('Huelva')  # Añade un nuevo elemento
cuenta1 = collections.Counter(lista1)
print(cuenta1)  
# Counter({'Granada': 3, 'Sevilla': 3, 'Huelva': 2})

# Creación de un objeto Counter a partir de un diccionario.

dicc1 = {'Granada': 3, 'Sevilla': 3, 'Huelva': 1}
cuenta2 = collections.Counter(dicc1)
cuenta3 = collections.Counter(Granada=3, Sevilla=3, Huelva=1)

# Un objeto contador se puede construir vacío y después 
# actualizar con el método update().

cuenta4 = collections.Counter()
print(cuenta4)
cuenta4.update('xxxyxzzyxyx')
print(cuenta4)  
# Counter({'x': 6, 'y': 3, 'z': 2})

cuenta4.update({'m':1, 'n':2})
print(cuenta4)  
# Counter({'x': 6, 'y': 3, 'n': 2, 'z': 2, 'm': 1})

# La forma de acceder al valor de algún elemento del Contador
# es igual que en un diccionario:
print(cuenta4['x'])  # 6
print(cuenta4['a'])  # 0

# Para obtener una lista con los elementos de un objeto Counter:
lista4 = list(cuenta4.elements())
print(lista4)  
# ['m', 'y', 'y', 'y', 'n', 'n', 'x', 
#  'x', 'x', 'x', 'x', 'x', 'z', 'z']

# Los elementos de la lista no estarán necesariamente ordenados. 
# Para ordenar una lista utilizaremos el método sort().
lista4.sort()
print(lista4)  
# ['m', 'n', 'n', 'x', 'x', 'x', 'x', 
#  'x', 'x', 'y', 'y', 'y', 'z', 'z']

# Para obtener una lista de tuplas con los elementos más
# comunes de un Contador.
print(cuenta4.most_common(1))
# Obtiene el elemento que más se repite: [('x', 6)]

print(cuenta4.most_common(3))
# 3 elementos más repetidos: [('x', 6), ('y', 3), ('n', 2)]

Para contar las palabras de una frase podemos crear una lista utilizando el método split() para dividir la frase en tantos trozos como palabras existan. Por defecto, split() utiliza el espacio en blanco como separador:

sagan = 'La ausencia de prueba no es prueba de ausencia'
lista5 = sagan.split()
cuenta5 = collections.Counter(lista5)

for clave, valor in cuenta5.items():
    print(clave,':',valor) 
    # no : 1, ausencia : 2, La : 1, de : 2, es : 1, prueba : 2

3 comentarios:

CARLOS_AAR dijo...

Hola, hay alguna función de python para contar en una lista de objetos, cuantos objetos hay con determinado atributo igual. Gracias

Pherkad dijo...

Hola Carlos

A continuación un ejemplo en el que se define una clase, se crean varios objetos y se imprimen el número de objetos que cumplen algunas condiciones:


class Led:
    def __init__(self, color, encendido):
        self.color = color
        self.encendido = encendido

Leds = [Led("azul", True),
        Led("blanco", False),
        Led("azul", False)]

print('Apagados', sum(not obj.encendido for obj in Leds))
print('Blancos', sum(obj.color == 'blanco' for obj in Leds))


Saludos y gracias por comentar

Wilson Daniel Moreno Prada dijo...

Hola carlos,
Lo podrias hacer de esta manera muy sencilla:
>>>[1,"a",1,0.1].count(1)
2