Recientemente noté que cuando estoy convirtiendo lista, setel orden de los elementos cambia y se ordena por carácter.
Considere este ejemplo:
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
Mis preguntas son:
- ¿Por qué está pasando esto?
- ¿Cómo puedo realizar operaciones de set (especialmente Set Difference) sin perder el orden inicial?

unique = list(dict.fromkeys([1, 2, 1]).keys()). Esto funciona porque losdicts conservan el orden de inserción ahora.Respuestas:
A
setes una estructura de datos desordenada, por lo que no conserva el orden de inserción.Depende de sus requisitos. Si tiene una lista normal y desea eliminar algún conjunto de elementos conservando el orden de la lista, puede hacerlo con una lista de comprensión:
Si necesita una estructura de datos que admita tanto las pruebas de membresía rápidas como la preservación del orden de inserción , puede usar las claves de un diccionario de Python, que a partir de Python 3.7 garantiza preservar el orden de inserción:
brealmente no es necesario pedirlo aquí, también podría usar unset. Tenga en cuenta quea.keys() - b.keys()devuelve la diferencia establecida como aset, por lo que no conservará el orden de inserción.En versiones anteriores de Python, puede usar
collections.OrderedDicten su lugar:fuente
Nonees un idioma único garantizado. En CPython, el costo real es solo el puntero (aunque ese costo siempre está ahí, pero para un dict, casi puede considerarNoney otros singletons o referencias compartidas "gratis"), por lo que una palabra de máquina, probablemente 8 bytes en computadoras modernas . Pero sí, no es tan eficiente en cuanto al espacio como podría serlo un conjunto.dict.fromkeys([1, 2, 1]).keys()porque losdicts regulares también conservan el orden.En Python 3.6,hay otra solución para Python 2 y 3:set()ahora debería mantener el orden, perofuente
x.indexse llama, se realiza una búsqueda lineal. Si está de acuerdo con la complejidad cuadrática, no hay razón para usar aseten primer lugar.set()no está ordenado en Python 3.6, ni siquiera como un detalle de implementación, estás pensando endictsinta menudo se hacen hash a sí mismos stackoverflow.com/questions/45581901/…x=[1,2,-1,20,6,210]convertirlo en un conjunto. Verá que no está ordenado en absoluto, probado en Python 3.6.Respondiendo a su primera pregunta, un conjunto es una estructura de datos optimizada para operaciones de conjuntos. Como un conjunto matemático, no impone ni mantiene ningún orden particular de los elementos. El concepto abstracto de un conjunto no impone el orden, por lo que no se requiere la implementación. Cuando crea un conjunto a partir de una lista, Python tiene la libertad de cambiar el orden de los elementos según las necesidades de la implementación interna que utiliza para un conjunto, que puede realizar operaciones de conjunto de manera eficiente.
fuente
eliminar duplicados y preservar el orden mediante la siguiente función
revisa este enlace
fuente
En matemáticas, hay conjuntos y conjuntos ordenados (osets).
En Python, solo los conjuntos se implementan directamente. Podemos emular osets con claves de dictado regulares ( 3.7+ ).
Dado
Código
Manifestación
Se eliminan las réplicas, se conserva el orden de inserción.
Operaciones tipo set en claves dictadas.
Detalles
Nota: una estructura desordenada no excluye los elementos ordenados. Más bien, el orden mantenido no está garantizado. Ejemplo:
Uno puede estar satisfecho al descubrir que una lista y conjunto múltiple (mset) son dos más fascinantes, estructuras de datos matemáticos:
Resumen
* Un multiset se puede emular indirectamente con
collections.Counter()un mapeo de multiplicidades (recuentos) similar a un dictado .fuente
Como se indica en otras respuestas, los conjuntos son estructuras de datos (y conceptos matemáticos) que no conservan el orden de los elementos:
Sin embargo, al usar una combinación de conjuntos y diccionarios, es posible que pueda lograr lo que quiera; intente usar estos fragmentos:
fuente
Sobre la base de la respuesta de Sven, encontré que el uso de collections.OrderedDict me ayudó a lograr lo que quieres y además me permite agregar más elementos al dict:
Si desea agregar elementos pero aún así tratarlo como un conjunto, puede hacer lo siguiente:
Y puede realizar una operación como z.keys () en el dict y obtener el conjunto:
fuente
list(z.keys())para obtener la salida de la lista.Una implementación del concepto de puntuación más alta anterior que lo devuelve a una lista:
Probado (brevemente) en Python 3.6 y Python 2.7.
fuente
En caso de que tenga una pequeña cantidad de elementos en sus dos listas iniciales en las que desee realizar una operación de diferenciación de conjuntos, en lugar de usar lo
collections.OrderedDictque complica la implementación y lo hace menos legible, puede usar:Su complejidad temporal no es tan buena, pero es ordenada y fácil de leer.
fuente
Es interesante que la gente siempre use "problema del mundo real" para bromear sobre la definición en ciencia teórica.
Si el conjunto tiene orden, primero debe resolver los siguientes problemas. Si su lista tiene elementos duplicados, ¿cuál debería ser el orden cuando la convierta en un conjunto? ¿Cuál es el orden si unimos dos conjuntos? ¿Cuál es el orden si intersecamos dos conjuntos con diferente orden en los mismos elementos?
Además, el conjunto es mucho más rápido en la búsqueda de una clave en particular, lo cual es muy bueno en el funcionamiento de conjuntos (y es por eso que necesita un conjunto, pero no una lista).
Si realmente le importa el índice, guárdelo como una lista. Si aún desea realizar la operación de conjunto en los elementos en muchas listas, la forma más sencilla es crear un diccionario para cada lista con las mismas claves en el conjunto junto con un valor de lista que contiene todo el índice de la clave en la lista original.
fuente
He aquí una forma sencilla de hacerlo:
fuente