Respuestas:
Si solo desea el recuento de un elemento, use el count
método:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
No use esto si desea contar varios elementos. Las llamadas count
en bucle requieren un pase separado sobre la lista para cada count
llamada, lo que puede ser catastrófico para el rendimiento. Si desea contar todos los elementos, o incluso solo varios, use Counter
, como se explica en las otras respuestas.
Úselo Counter
si está utilizando Python 2.7 o 3.xy desea el número de ocurrencias para cada elemento:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
isinstance
. Entonces, si está seguro de los datos con los que está trabajando, podría ser mejor escribir una función personalizada sin verificación de tipo e instancia.
isinstance
llamadas? Incluso con millones de cadenas, llamar Counter
solo implica una isinstance
llamada, para verificar si su argumento es un mapeo. Lo más probable es que hayas juzgado mal lo que está comiendo todo tu tiempo.
Counter
ha llevado a contar grandes iterables, en lugar de contar muchos iterables. Contar un iterativo de un millón de cadenas será más rápido Counter
que con una implementación manual. Si desea llamar update
con muchos iterables, puede acelerar las cosas uniéndolas en un solo iterable itertools.chain
.
Contando las ocurrencias de un artículo en una lista
Para contar las ocurrencias de un solo elemento de la lista, puede usar count()
>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2
Contar las ocurrencias de todos los elementos de una lista también se conoce como "contar" una lista o crear un contador de conteo.
Contando todos los artículos con count ()
Para contar las ocurrencias de los elementos en l
uno, simplemente puede usar una lista de comprensión y el count()
método
[[x,l.count(x)] for x in set(l)]
(o de manera similar con un diccionario dict((x,l.count(x)) for x in set(l))
)
Ejemplo:
>>> l = ["a","b","b"]
>>> [[x,l.count(x)] for x in set(l)]
[['a', 1], ['b', 2]]
>>> dict((x,l.count(x)) for x in set(l))
{'a': 1, 'b': 2}
Contando todos los artículos con Counter ()
Alternativamente, está la Counter
clase más rápida de la collections
biblioteca.
Counter(l)
Ejemplo:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
¿Cuánto más rápido es Counter?
Verifiqué cuánto más rápido Counter
es para las listas de conteo. Probé ambos métodos con algunos valores de n
y parece que Counter
es más rápido en un factor constante de aproximadamente 2.
Aquí está el script que usé:
from __future__ import print_function
import timeit
t1=timeit.Timer('Counter(l)', \
'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
)
t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]',
'import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
)
print("Counter(): ", t1.repeat(repeat=3,number=10000))
print("count(): ", t2.repeat(repeat=3,number=10000)
Y la salida:
Counter(): [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count(): [7.779430688009597, 7.962715800967999, 8.420845870045014]
Counter
es mucho más rápido para listas más grandes. El método de comprensión de la lista es O (n ^ 2), Counter
debe ser O (n).
isinstance
. Entonces, si está seguro de los datos con los que está trabajando, podría ser mejor escribir una función personalizada sin verificación de tipo e instancia.
Otra forma de obtener el número de ocurrencias de cada elemento, en un diccionario:
dict((i, a.count(i)) for i in a)
n * (number of different items)
operaciones, sin contar el tiempo que lleva construir el conjunto. Usar collections.Counter
es realmente mucho mejor.
i
, porque intentará ingresar múltiples claves del mismo valor en un diccionario. dict((i, a.count(i)) for i in a)
list.count(x)
devuelve el número de veces que x
aparece en una lista
ver: http://docs.python.org/tutorial/datastructures.html#more-on-lists
Dado un elemento, ¿cómo puedo contar sus ocurrencias en una lista en Python?
Aquí hay una lista de ejemplos:
>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
list.count
Ahí está el list.count
método
>>> l.count('b')
4
Esto funciona bien para cualquier lista. Las tuplas también tienen este método:
>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6
collections.Counter
Y luego están las colecciones. Contador. Puede volcar cualquier iterable en un Contador, no solo una lista, y el Contador retendrá una estructura de datos de los recuentos de los elementos.
Uso:
>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4
Los contadores se basan en diccionarios de Python, sus claves son los elementos, por lo que las claves deben ser hashaable. Básicamente son como conjuntos que permiten elementos redundantes en ellos.
collections.Counter
Puede sumar o restar con iterables de su contador:
>>> c.update(list('bbb'))
>>> c['b']
7
>>> c.subtract(list('bbb'))
>>> c['b']
4
Y también puede realizar operaciones de conjuntos múltiples con el contador:
>>> c2 = Counter(list('aabbxyz'))
>>> c - c2 # set difference
Counter({'a': 3, 'c': 3, 'b': 2, 'd': 2, 'e': 1})
>>> c + c2 # addition of all elements
Counter({'a': 7, 'b': 6, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c | c2 # set union
Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c & c2 # set intersection
Counter({'a': 2, 'b': 2})
Otra respuesta sugiere:
¿Por qué no usar pandas?
Pandas es una biblioteca común, pero no está en la biblioteca estándar. Agregarlo como un requisito no es trivial.
Hay soluciones integradas para este caso de uso en el objeto de lista en sí, así como en la biblioteca estándar.
Si su proyecto aún no requiere pandas, sería una tontería exigirlo solo para esta funcionalidad.
Comparé todas las soluciones sugeridas (y algunas nuevas) con perfplot (un pequeño proyecto mío).
Para matrices lo suficientemente grandes, resulta que
numpy.sum(numpy.array(a) == 1)
es un poco más rápido que las otras soluciones.
Como se estableció anteriormente ,
numpy.bincount(a)
es lo que quieres
Código para reproducir las tramas:
from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot
def counter(a):
return Counter(a)
def count(a):
return dict((i, a.count(i)) for i in set(a))
def bincount(a):
return numpy.bincount(a)
def pandas_value_counts(a):
return pandas.Series(a).value_counts()
def occur_dict(a):
d = {}
for i in a:
if i in d:
d[i] = d[i]+1
else:
d[i] = 1
return d
def count_unsorted_list_items(items):
counts = defaultdict(int)
for item in items:
counts[item] += 1
return dict(counts)
def operator_countof(a):
return dict((i, operator.countOf(a, i)) for i in set(a))
perfplot.show(
setup=lambda n: list(numpy.random.randint(0, 100, n)),
n_range=[2**k for k in range(20)],
kernels=[
counter, count, bincount, pandas_value_counts, occur_dict,
count_unsorted_list_items, operator_countof
],
equality_check=None,
logx=True,
logy=True,
)
2)
from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot
def counter(a):
return Counter(a)
def count(a):
return dict((i, a.count(i)) for i in set(a))
def bincount(a):
return numpy.bincount(a)
def pandas_value_counts(a):
return pandas.Series(a).value_counts()
def occur_dict(a):
d = {}
for i in a:
if i in d:
d[i] = d[i]+1
else:
d[i] = 1
return d
def count_unsorted_list_items(items):
counts = defaultdict(int)
for item in items:
counts[item] += 1
return dict(counts)
def operator_countof(a):
return dict((i, operator.countOf(a, i)) for i in set(a))
perfplot.show(
setup=lambda n: list(numpy.random.randint(0, 100, n)),
n_range=[2**k for k in range(20)],
kernels=[
counter, count, bincount, pandas_value_counts, occur_dict,
count_unsorted_list_items, operator_countof
],
equality_check=None,
logx=True,
logy=True,
)
Si puede usar pandas
, entonces value_counts
está allí para rescatarlo.
>>> import pandas as pd
>>> a = [1, 2, 3, 4, 1, 4, 1]
>>> pd.Series(a).value_counts()
1 3
4 2
3 1
2 1
dtype: int64
También clasifica automáticamente el resultado según la frecuencia.
Si desea que el resultado esté en una lista de la lista, haga lo siguiente
>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]
¿Por qué no usar pandas?
import pandas as pd
l = ['a', 'b', 'c', 'd', 'a', 'd', 'a']
# converting the list to a Series and counting the values
my_count = pd.Series(l).value_counts()
my_count
Salida:
a 3
d 2
b 1
c 1
dtype: int64
Si está buscando un conteo de un elemento en particular, diga a , intente:
my_count['a']
Salida:
3
Tuve este problema hoy y lancé mi propia solución antes de pensar en comprobar SO. Esta:
dict((i,a.count(i)) for i in a)
es muy, muy lento para listas grandes. Mi solución
def occurDict(items):
d = {}
for i in items:
if i in d:
d[i] = d[i]+1
else:
d[i] = 1
return d
en realidad es un poco más rápido que la solución Counter, al menos para Python 2.7.
# Python >= 2.6 (defaultdict) && < 2.7 (Counter, OrderedDict)
from collections import defaultdict
def count_unsorted_list_items(items):
"""
:param items: iterable of hashable items to count
:type items: iterable
:returns: dict of counts like Py2.7 Counter
:rtype: dict
"""
counts = defaultdict(int)
for item in items:
counts[item] += 1
return dict(counts)
# Python >= 2.2 (generators)
def count_sorted_list_items(items):
"""
:param items: sorted iterable of items to count
:type items: sorted iterable
:returns: generator of (item, count) tuples
:rtype: generator
"""
if not items:
return
elif len(items) == 1:
yield (items[0], 1)
return
prev_item = items[0]
count = 1
for item in items[1:]:
if prev_item == item:
count += 1
else:
yield (prev_item, count)
count = 1
prev_item = item
yield (item, count)
return
import unittest
class TestListCounters(unittest.TestCase):
def test_count_unsorted_list_items(self):
D = (
([], []),
([2], [(2,1)]),
([2,2], [(2,2)]),
([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
)
for inp, exp_outp in D:
counts = count_unsorted_list_items(inp)
print inp, exp_outp, counts
self.assertEqual(counts, dict( exp_outp ))
inp, exp_outp = UNSORTED_WIN = ([2,2,4,2], [(2,3), (4,1)])
self.assertEqual(dict( exp_outp ), count_unsorted_list_items(inp) )
def test_count_sorted_list_items(self):
D = (
([], []),
([2], [(2,1)]),
([2,2], [(2,2)]),
([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
)
for inp, exp_outp in D:
counts = list( count_sorted_list_items(inp) )
print inp, exp_outp, counts
self.assertEqual(counts, exp_outp)
inp, exp_outp = UNSORTED_FAIL = ([2,2,4,2], [(2,3), (4,1)])
self.assertEqual(exp_outp, list( count_sorted_list_items(inp) ))
# ... [(2,2), (4,1), (2,1)]
Lo más rápido es usar un bucle for y almacenarlo en un Dict.
import time
from collections import Counter
def countElement(a):
g = {}
for i in a:
if i in g:
g[i] +=1
else:
g[i] =1
return g
z = [1,1,1,1,2,2,2,2,3,3,4,5,5,234,23,3,12,3,123,12,31,23,13,2,4,23,42,42,34,234,23,42,34,23,423,42,34,23,423,4,234,23,42,34,23,4,23,423,4,23,4]
#Solution 1 - Faster
st = time.monotonic()
for i in range(1000000):
b = countElement(z)
et = time.monotonic()
print(b)
print('Simple for loop and storing it in dict - Duration: {}'.format(et - st))
#Solution 2 - Fast
st = time.monotonic()
for i in range(1000000):
a = Counter(z)
et = time.monotonic()
print (a)
print('Using collections.Counter - Duration: {}'.format(et - st))
#Solution 3 - Slow
st = time.monotonic()
for i in range(1000000):
g = dict([(i, z.count(i)) for i in set(z)])
et = time.monotonic()
print(g)
print('Using list comprehension - Duration: {}'.format(et - st))
Resultado
#Solution 1 - Faster
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 234: 3, 23: 10, 12: 2, 123: 1, 31: 1, 13: 1, 42: 5, 34: 4, 423: 3}
Simple for loop and storing it in dict - Duration: 12.032000000000153
#Solution 2 - Fast
Counter({23: 10, 4: 6, 2: 5, 42: 5, 1: 4, 3: 4, 34: 4, 234: 3, 423: 3, 5: 2, 12: 2, 123: 1, 31: 1, 13: 1})
Using collections.Counter - Duration: 15.889999999999418
#Solution 3 - Slow
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 34: 4, 423: 3, 234: 3, 42: 5, 12: 2, 13: 1, 23: 10, 123: 1, 31: 1}
Using list comprehension - Duration: 33.0
itertools.groupby()
Otra posibilidad para obtener el recuento de todos los elementos de la lista podría ser mediante itertools.groupby()
.
Con recuentos "duplicados"
from itertools import groupby
L = ['a', 'a', 'a', 't', 'q', 'a', 'd', 'a', 'd', 'c'] # Input list
counts = [(i, len(list(c))) for i,c in groupby(L)] # Create value-count pairs as list of tuples
print(counts)
Devoluciones
[('a', 3), ('t', 1), ('q', 1), ('a', 1), ('d', 1), ('a', 1), ('d', 1), ('c', 1)]
Observe cómo combinó los primeros tres a
como el primer grupo, mientras que otros grupos a
están presentes más abajo en la lista. Esto sucede porque la lista de entrada L
no se ordenó. Esto puede ser un beneficio a veces si los grupos deberían estar separados.
Con recuentos únicos
Si se desean recuentos de grupos únicos, simplemente ordene la lista de entrada:
counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)
Devoluciones
[('a', 5), ('c', 1), ('d', 2), ('q', 1), ('t', 1)]
Nota: Para crear recuentos únicos, muchas de las otras respuestas proporcionan un código más fácil y más legible en comparación con la groupby
solución. Pero se muestra aquí para dibujar un paralelo al ejemplo de conteo duplicado.
Se sugirió usar el bincount de numpy , sin embargo, solo funciona para matrices 1d con enteros no negativos . Además, la matriz resultante puede ser confusa (contiene las ocurrencias de los enteros de mínimo a máximo de la lista original, y establece en 0 los enteros faltantes).
Una mejor manera de hacerlo con numpy es usar la función única con el atributo return_counts
establecido en True. Devuelve una tupla con una matriz de valores únicos y una matriz de las ocurrencias de cada valor único.
# a = [1, 1, 0, 2, 1, 0, 3, 3]
a_uniq, counts = np.unique(a, return_counts=True) # array([0, 1, 2, 3]), array([2, 3, 1, 2]
y luego podemos emparejarlos como
dict(zip(a_uniq, counts)) # {0: 2, 1: 3, 2: 1, 3: 2}
También funciona con otros tipos de datos y "listas 2d", p. Ej.
>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}
Aunque es una pregunta muy antigua, pero como no encontré una sola línea, hice una.
# original numbers in list
l = [1, 2, 2, 3, 3, 3, 4]
# empty dictionary to hold pair of number and its count
d = {}
# loop through all elements and store count
[ d.update( {i:d.get(i, 0)+1} ) for i in l ]
print(d)
También puede usar el countOf
método de un módulo incorporado operator
.
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
countOf
se implementa? ¿Cómo se compara con lo más obvio list.count
(que se beneficia de la implementación de C)? ¿Hay alguna ventaja?
Puede no ser el más eficiente, requiere un pase adicional para eliminar duplicados.
Implementación funcional:
arr = np.array(['a','a','b','b','b','c'])
print(set(map(lambda x : (x , list(arr).count(x)) , arr)))
devoluciones :
{('c', 1), ('b', 3), ('a', 2)}
o volver como dict
:
print(dict(map(lambda x : (x , list(arr).count(x)) , arr)))
devoluciones :
{'b': 3, 'c': 1, 'a': 2}
sum([1 for elem in <yourlist> if elem==<your_value>])
Esto devolverá la cantidad de ocurrencias de your_value
si desea una serie de ocurrencias para el elemento en particular:
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> single_occurrences = Counter(z)
>>> print(single_occurrences.get("blue"))
3
>>> print(single_occurrences.values())
dict_values([3, 2, 1])
def countfrequncyinarray(arr1):
r=len(arr1)
return {i:arr1.count(i) for i in range(1,r+1)}
arr1=[4,4,4,4]
a=countfrequncyinarray(arr1)
print(a)
l2=[1,"feto",["feto",1,["feto"]],['feto',[1,2,3,['feto']]]]
count=0
def Test(l):
global count
if len(l)==0:
return count
count=l.count("feto")
for i in l:
if type(i) is list:
count+=Test(i)
return count
print(Test(l2))
esto contará recursivamente o buscará el elemento en la lista incluso si está en la lista de listas
mylist = [1,7,7,7,3,9,9,9,7,9,10,0] print sorted(set([i for i in mylist if mylist.count(i)>2]))