¿Cómo puedo contar las ocurrencias de un elemento de lista?

Dado un elemento, ¿cómo puedo contar sus ocurrencias en una lista en Python?

Si solo quieres el conteo de un artículo, usa el método de count :

 >>> [1, 2, 3, 4, 1, 4, 1].count(1) 3 

No uses esto si quieres contar varios artículos. El count llamadas en un bucle requiere un pase por separado sobre la lista para cada llamada de count , lo que puede ser catastrófico para el rendimiento. Si desea contar todos los elementos, o incluso solo varios elementos, use Counter , como se explica en las otras respuestas.

Si está utilizando Python 2.7 o 3 y desea un número de apariciones para cada elemento:

 >>> from collections import Counter >>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red'] >>> Counter(z) Counter({'blue': 3, 'red': 2, 'yellow': 1}) 

Contando las ocurrencias de un elemento 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 “recuento” de una lista, o creación de un contador de recuento.

Contando todos los artículos con cuenta ()

Para contar las ocurrencias de elementos en l , simplemente puede usar una lista de comprensión y el método count()

 [[x,l.count(x)] for x in set(l)] 

(o similarmente 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 contador ()

Alternativamente, está la clase Counter más rápida de la biblioteca de collections

 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 el contador?

Comprobé cuánto más rápido es el Counter para las listas de recuento. Probé ambos métodos con unos pocos valores de n y parece que Counter es más rápido por un factor constante de aproximadamente 2.

Aquí está el guión que utilicé:

 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] 

Otra forma de obtener el número de apariciones de cada elemento, 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 método list.count

 >>> 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. Puede volcar cualquier iterable en un contador, no solo en una lista, y el contador conservará una estructura de datos de los conteos de los elementos.

Uso:

 >>> from collections import Counter >>> c = Counter(l) >>> c['b'] 4 

Los contadores se basan en los diccionarios de Python, sus claves son los elementos, por lo que las claves deben ser hashable. Básicamente son como conjuntos que permiten elementos redundantes en ellos.

Uso adicional de las collections.Counter

Puedes sumr o restar con iterables de tu 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}) 

¿Por qué no los pandas?

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 la lista de objetos en sí, así como en la biblioteca estándar.

Si su proyecto no requiere pandas, sería una tontería convertirlo en un requisito solo para esta funcionalidad.

Si desea contar todos los valores a la vez , puede hacerlo muy rápido utilizando matrices bincount y bincount siguiente manera

 import numpy as np a = np.array([1, 2, 3, 4, 1, 4, 1]) np.bincount(a) 

lo que da

 >>> array([0, 3, 1, 1, 2]) 

He comparado todas las soluciones sugeridas (y algunas nuevas) con perfplot (un pequeño proyecto mío).

Contando un artículo

Para matrices suficientemente grandes, resulta que

 numpy.sum(numpy.array(a) == 1) 

Es un poco más rápido que las otras soluciones.

introduzca la descripción de la imagen aquí

Contando todos los artículos

Como se estableció antes ,

 numpy.bincount(a) 

es lo que quieres

introduzca la descripción de la imagen aquí


Código para reproducir las plots:

 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 puedes usar pandas , entonces value_counts está ahí para el rescate.

 >>> 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 en función de 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 recuento de un elemento en particular, diga a , intente:

 my_count['a'] 

Salida:

 3 
 # 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)] 

Tuve este problema hoy y presenté mi propia solución antes de pensar en verificar 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 

es en realidad un poco más rápido que la solución Counter, al menos para Python 2.7.

Para contar el número de elementos diversos que tienen un tipo común:

 li = ['A0','c5','A8','A2','A5','c2','A3','A9'] print sum(1 for el in li if el[0]=='A' and el[1] in '01234') 

da

3 , no 6

 from collections import Counter country=['Uruguay', 'Mexico', 'Uruguay', 'France', 'Mexico'] count_country = Counter(country) output_list= [] for i in count_country: output_list.append([i,count_country[i]]) print output_list 

Lista de salida:

 [['Mexico', 2], ['France', 1], ['Uruguay', 2]] 

Se sugirió usar bincount de numpy , sin embargo, solo funciona para matrices 1d con enteros no negativos . Además, la matriz resultante puede ser confusa (contiene las apariciones 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 los valores únicos y una matriz de las apariciones 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”, por ejemplo,

 >>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']] >>> dict(zip(*np.unique(a, return_counts=True))) {'a': 3, 'b': 3, 'c': 2} 

Cuenta de todos los elementos con itertools.groupby()

Una posibilidad adicional para obtener el recuento de todos los elementos de la lista podría ser mediante itertools.groupby() .

Con cuentas “duplicadas”

 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ó las tres primeras a ‘s como el primer grupo, mientras que otros grupos de a están presentes más abajo en la lista. Esto sucede porque la lista de entrada L no estaba ordenada. Esto puede ser un beneficio a veces si los grupos deberían estar separados.

Con cuentas únicas.

Si se desean conteos 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)] 

También puede usar el método countOf de un operator módulo incorporado.

 >>> import operator >>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1) 3 

Puede que no sea el más eficiente, requiere un pase extra 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 devolver como dict :

 print(dict(map(lambda x : (x , list(arr).count(x)) , arr))) 

devoluciones :

 {'b': 3, 'c': 1, 'a': 2} 

A continuación se presentan las tres soluciones:

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 
 sum([1 for elem in  if elem==]) 

Esto devolverá la cantidad de ocurrencias de su_valor

Si desea una serie de apariciones 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)