create - python set[]
Establecer el orden de los elementos de los cambios? (7)
Un
set
es una estructura de datos desordenada.No use un
set
, sino más biencollections.OrderedDict
:>>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210]) >>> b = collections.OrderedDict.fromkeys([6, 20, 1]) >>> collections.OrderedDict.fromkeys(x for x in a if x not in b) OrderedDict([(2, None), (210, None)])
Tenga en cuenta que el orden de
b
no importa, por lo que podría ser iterable, pero debería ser iterable y admitir O (1) pruebas de membresía.
Editar : la respuesta anterior asume que desea poder realizar operaciones (ordenadas) en todas las colecciones existentes, en particular también en el resultado de una operación anterior. Si esto no es necesario, simplemente puede usar listas para algunas colecciones y conjuntos para otras, por ejemplo
>>> a = [1, 2, 20, 6, 210]
>>> b = set([6, 20, 1])
>>> [x for x in a if x not in b]
[2, 210]
Esto pierde el orden de b
, no permite pruebas rápidas de membresía en a
y el resultado. Los conjuntos permiten realizar pruebas de membresía rápidas y las listas mantienen el orden. Si necesita estas dos características en la misma colección, use collections.OrderedDict
.
Recientemente me di cuenta de que cuando estoy convirtiendo la lista para establecer el orden o los elementos se cambia y se ordena por carácter.
Considera 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 configurar operaciones (especialmente Establecer diferencia) sin perder el orden inicial?
Al responder a su primera pregunta, establecer es una estructura de datos optimizada para las operaciones de conjunto, y al igual que un conjunto matemático, no impone / mantiene ningún orden particular de los elementos. El concepto abstracto de conjunto no impone orden, tampoco lo hace la implementación. Cuando crea un conjunto a partir de una lista, python se toma la libertad de cambiar el orden de los elementos para las necesidades de la implementación interna que utiliza para un conjunto, que es capaz de realizar las operaciones establecidas de manera eficiente.
Aquí hay una manera fácil de hacerlo:
x=[1,2,20,6,210]
print sorted(set(x))
Como se denota 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 obtener la cantidad que desee: intente utilizar estos fragmentos:
# save the element order in a dict:
x_dict = dict(x,y for y, x in enumerate(my_list) )
x_set = set(my_list)
#perform desired set operations
...
#retrieve ordered list from the set:
new_list = [None] * len(new_set)
for element in new_set:
new_list[x_dict[element]] = element
Sobre la base de la respuesta de Sven, encontré el uso de colecciones. Ordenado como me ayudó a lograr lo que quieres y me permite agregar más elementos a la dict:
import collections
x=[1,2,20,6,210]
z=collections.OrderedDict.fromkeys(x)
z
OrderedDict([(1, None), (2, None), (20, None), (6, None), (210, None)])
Si desea agregar elementos pero todavía lo trata como un conjunto, puede hacer lo siguiente:
z[''nextitem'']=None
Y puede realizar una operación como z.keys () en el dict y obtener el conjunto:
z.keys()
[1, 2, 20, 6, 210]
Una implementación del concepto de puntaje más alto arriba que lo trae de vuelta a una lista:
def SetOfListInOrder(incominglist):
from collections import OrderedDict
outtemp = OrderedDict()
for item in incominglist:
outtemp[item] = None
return(list(outtemp))
Probado (brevemente) en Python 3.6 y Python 2.7.
En Python 3.6, hay otra solución para Python 2 y 3: set()
ahora debe mantener el orden, pero
>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]