dict - Colecciones de Python. Contador: complejidad más_común
python 3.6 collections (2)
Desde el código fuente de collections.py , vemos que si no especificamos un número de elementos devueltos, most_common devuelve una lista ordenada de los conteos. Este es un algoritmo O(n log n) .
Si usamos most_common para devolver k > 1 elementos, entonces usamos el método heapq de heapq . Este es un algoritmo O(k) + O((n - k) log k) + O(k log k) , que es muy bueno para una pequeña constante k , ya que es esencialmente lineal. La parte O(k) proviene de la heapificación de los recuentos de k iniciales, la segunda parte de n - k llama al método heappushpop y la tercera parte de la clasificación del montón final de k elementos. Como k <= n podemos concluir que la complejidad es:
O (n log k)
Si k = 1 entonces es fácil mostrar que la complejidad es:
En)
Me pregunto cuál es la complejidad de la función most_common proporcionada por las collections.Counter most_common el objeto en Python 2.7.
Más específicamente, ¿el Counter mantiene algún tipo de lista ordenada mientras se está actualizando, lo que permite realizar la operación most_common más rápido que O(n) cuando n es el número de elementos (únicos) agregados al contador? Para su información, estoy procesando una gran cantidad de datos de texto tratando de encontrar los tokens más frecuentes.
Revisé la documentación oficial ( https://docs.python.org/2/library/collections.html#collections.Counter ), la wiki de CPython ( https://wiki.python.org/moin/TimeComplexity ) pero pude No encuentra la respuesta. ¡Gracias de antemano!
Romain
La fuente muestra exactamente lo que sucede:
def most_common(self, n=None):
''''''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter(''abracadabra'').most_common(3)
[(''a'', 5), (''r'', 2), (''b'', 2)]
''''''
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.iteritems(), key=_itemgetter(1), reverse=True)
return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1))