Counter — Contar Objetos Hashables¶
Un Counter
es un contenedor que registra cuántas veces se agregan valores
equivalentes. Se puede usar para implementar los mismos algoritmos para los
cuales otros lenguajes comúnmente usan una bolsa o una estructuras de conjunto
múltiple.
Inicializando¶
Counter
admite tres formas de inicialización. Su constructor se puede
llamar con una secuencia de elementos, un diccionario que contiene claves y
recuentos, o usando argumentos de palabra clave que mapean nombres cadena a los
conteos.
import collections
print(collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print(collections.Counter({'a': 2, 'b': 3, 'c': 1}))
print(collections.Counter(a=2, b=3, c=1))
Los resultados de las tres formas de inicialización son los mismos.
$ python3 collections_counter_init.py
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Un Counter
vacío se puede construir sin argumentos y ser poblado a través
del método update()
.
import collections
c = collections.Counter()
print('Initial :', c)
c.update('abcdaab')
print('Sequence:', c)
c.update({'a': 1, 'd': 5})
print('Dict :', c)
Los valores de recuento se incrementan en función de los datos nuevos, en lugar
de ser reemplazados. En el ejemplo anterior, el recuento para a
pasa de
3
a 4
.
$ python3 collections_counter_update.py
Initial : Counter()
Sequence: Counter({'a': 3, 'b': 2, 'c': 1, 'd': 1})
Dict : Counter({'d': 6, 'a': 4, 'b': 2, 'c': 1})
Accediendo a los recuentos¶
Una vez que se llena un Counter
, se pueden recuperar sus valores usando la
interfaz de diccionario.
import collections
c = collections.Counter('abcdaab')
for letter in 'abcde':
print('{} : {}'.format(letter, c[letter]))
Counter
no eleva KeyError
para elementos desconocidos. Si un valor no
se ha visto en la entrada (como con e
en este ejemplo), su recuento es
0
.
$ python3 collections_counter_get_values.py
a : 3
b : 2
c : 1
d : 1
e : 0
El método elements()
devuelve un iterador que produce todos los elementos
conocidos por el Counter
.
import collections
c = collections.Counter('extremely')
c['z'] = 0
print(c)
print(list(c.elements()))
El orden de los elementos no está garantizado, y los elementos con conteos menores o iguales a cero no están incluidos.
$ python3 collections_counter_elements.py
Counter({'e': 3, 'x': 1, 'm': 1, 't': 1, 'y': 1, 'l': 1, 'r': 1,
'z': 0})
['x', 'm', 't', 'e', 'e', 'e', 'y', 'l', 'r']
Usa most_common()
para producir una secuencia de n valores de entrada
encontrados con mayor frecuencia y sus respectivos conteos.
import collections
c = collections.Counter()
with open('/usr/share/dict/words', 'rt') as f:
for line in f:
c.update(line.rstrip().lower())
print('Most common:')
for letter, count in c.most_common(3):
print('{}: {:>7}'.format(letter, count))
Este ejemplo cuenta las letras que aparecen en todas las palabras del
diccionario del sistema para producir una distribución de frecuencia, luego
imprime las tres letras más comunes. Dejando fuera el argumento para
most_common()
produce una lista de todos los elementos, en orden de
frecuencia.
$ python3 collections_counter_most_common.py
Most common:
e: 235331
i: 201032
a: 199554
Aritmética¶
Las instancias Counter
admiten aritmética y establecen operaciones para
agregar resultados. Este ejemplo muestra los operadores estándar para crear
nuevas instancias Counter
, pero los operadores in situ +=
, -=
,
&=
, y |=
también son admitidos.
import collections
c1 = collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = collections.Counter('alphabet')
print('C1:', c1)
print('C2:', c2)
print('\nCombined counts:')
print(c1 + c2)
print('\nSubtraction:')
print(c1 - c2)
print('\nIntersection (taking positive minimums):')
print(c1 & c2)
print('\nUnion (taking maximums):')
print(c1 | c2)
Cada vez que se produce un nuevo Counter
a través de una operación,
cualquier elementos con recuentos cero o negativos se descartan. El conteo de
a
es el mismo en c1
y c2
, por lo que la resta lo deja en cero.
$ python3 collections_counter_arithmetic.py
C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'b': 1, 'p': 1, 't': 1, 'l': 1, 'e': 1, 'h': 1})
Combined counts:
Counter({'b': 4, 'a': 4, 'p': 1, 't': 1, 'c': 1, 'e': 1, 'l': 1, 'h': 1})
Subtraction:
Counter({'b': 2, 'c': 1})
Intersection (taking positive minimums):
Counter({'a': 2, 'b': 1})
Union (taking maximums):
Counter({'b': 3, 'a': 2, 'p': 1, 't': 1, 'c': 1, 'e': 1, 'l': 1, 'h': 1})