Con lo cual me refiero a una estructura con:
- O (log n) complejidad para
x.push()
operaciones - O (log n) complejidad para encontrar un elemento
- O (n) complejidad para calcular
list(x)
que se ordenará
También tenía una pregunta relacionada sobre el rendimiento list(...).insert(...)
que ahora está aquí .
memcpy
sigue siendo una operación O (n) . No estoy seguro de cómo Python implementa las listas exactamente , pero mi apuesta sería que se almacenan en la memoria contigua (ciertamente no como una lista vinculada). Si eso es así, la inserción con labisect
que demuestre tendrá complejidad O (n) .Respuestas:
La lista estándar de Python no está ordenada de ninguna forma. El módulo heapq estándar se puede usar para agregar O (log n) a una lista existente y eliminar el más pequeño de O (log n), pero no es una lista ordenada en su definición.
Existen varias implementaciones de árboles equilibrados para Python que satisfagan sus necesidades, por ejemplo rbtree , RBTree o pyavl .
fuente
¿Hay alguna razón particular para sus requisitos de Big-O? ¿O simplemente quieres que sea rápido? El módulo sortedcontainers es Python puro y rápido (como en implementaciones rápidas como C como blist y rbtree).
La comparación de rendimiento muestra los puntos de referencia más rápido o a la par con el tipo de lista ordenada de blist. Tenga en cuenta también que rbtree, RBTree y PyAVL proporcionan dict ordenados y establecen tipos, pero no tienen un tipo de lista ordenada.
Si el rendimiento es un requisito, recuerde siempre hacer una referencia. Un módulo que corrobore la afirmación de ser rápido con la notación Big-O debe ser sospechoso hasta que también muestre comparaciones de referencia.
Descargo de responsabilidad: soy el autor del módulo de contenedores ordenados de Python.
Instalación:
Uso:
fuente
0.0845024989976
para SortedList.add () vs0.596589182518
for bisect.insort (), ¡por lo tanto, una diferencia de 7x en velocidad! Y espero que la brecha de velocidad aumente con la longitud de la lista, ya que la clasificación de inserción de contenedores ordenados funciona en O (log n) mientras que bisect.insort () en O (n).O(n)
Aunque todavía nunca he verificado las velocidades de "gran O" de las operaciones básicas de la lista de Python, el
bisect
módulo estándar probablemente también valga la pena mencionar en este contexto:PD. Ah, lo siento,
bisect
se menciona en la pregunta de referencia. Aún así, creo que no será mucho daño si esta información está aquí)PPS Y las listas de CPython son en realidad matrices (no, digamos, listas de omisión o etc.). Bueno, supongo que tienen que ser algo simple, pero en cuanto a mí, el nombre es un poco engañoso.
Entonces, si no me equivoco, las velocidades de bisección / lista probablemente serían:
Upd. Después de una discusión en los comentarios, permítanme vincular aquí estas preguntas SO: ¿Cómo se implementa la lista de Python y cuál es la complejidad del tiempo de ejecución de las funciones de la lista de Python?
fuente
fuente
Aunque (todavía) no proporciona una función de búsqueda personalizada, el
heapq
módulo puede satisfacer sus necesidades. Implementa una cola de montón utilizando una lista regular. Tendría que escribir su propia prueba de membresía eficiente que haga uso de la estructura interna de la cola (eso se puede hacer en O (log n) , yo diría ...). Hay un inconveniente: extraer una lista ordenada tiene complejidad O (n log n) .fuente
Yo usaría los módulos
biscect
osortedcontainers
. Realmente no tengo experiencia, pero creo que elheapq
módulo funciona. Contiene unHeap Queue
fuente
Puede que no sea difícil implementar su propia lista de clasificación en Python. A continuación se muestra una prueba de concepto:
========= Resultados ============
[3, 10, 14, 17, 23, 44, 45, 45, 50, 66, 73, 77, 79, 84, 85, 86, 91, 95, 101]
[3, 10, 14, 17, 23, 44, 45, 45, 50, 66, 73, 77, 79, 84, 85, 86, 91, 95, 99, 101]
101
3
50
fuente