ordereddict dict python python-2.7 counter python-collections

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))