¿Se ordenan los conjuntos como dicts en python3.6?
set python-3.6 (2)
Debido a los cambios en la implementación de
dict
en Python 3.6, ahora se ordena de forma predeterminada.
¿
set
s preservar el orden ahora también?
No pude encontrar ninguna información al respecto, pero como ambas estructuras de datos son muy similares en la forma en que funcionan bajo el capó, pensé que podría ser el caso.
Sé que no hay promesa de que se ordenen
dict
s en todos los casos, pero lo son la mayoría de las veces.
Como se indica en los documentos de Python:
El aspecto de preservación del orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en él
No, los
set
todavía no están ordenados.
Puede verificar esto simplemente mostrando un
set
que debe tener un "orden hash bien definido"
1
para asegurarse de que no obtenemos accidentalmente un
set
que parece ordenado pero en realidad no lo es:
>>> a_set = {3,2,1}
>>> a_set
{1, 2, 3}
>>> list(a_set)
[1, 2, 3]
Si se ordenara, esperaría
{3, 2, 1}
y
[3, 2, 1]
como resultado de los ejemplos.
Mientras que los
dict
s están realmente ordenados (el mismo ejemplo está un poco modificado):
>>> a_dict = {3: 3, 2: 2, 1:1}
>>> a_dict
{3: 3, 2: 2, 1: 1}
>>> list(a_dict)
[3, 2, 1]
1 "orden hash bien definido":
Para los enteros que satisfacen
0 <= integer < sys.hash_info.modulus
el
hash
es solo el número mismo.
Eso significa que si el conjunto está ordenado "basado" en el hash (y no ordenado según el "tiempo" de inserción) y los valores hash no chocan (es por eso que usé números pequeños y números que solo difieren en uno). debe ser determinista porque ocupan ranuras dentro del conjunto que están una al lado de la otra:
- Ya sea de menor a mayor
- o desde un valor específico hasta el más alto y luego desde el más pequeño hasta el valor específico. Este caso ocurre si la siguiente ranura libre (en el sentido de la vecina) en el conjunto es la primera.
Como ejemplo para este último:
>>> a_set = {6,7,8,9}
>>> a_set
{8, 9, 6, 7}
set
no están ordenados en Python 3.6, ni siquiera como un detalle de implementación de CPython.
Un ejemplo simple ilustra esto:
>>> import string
>>> string.digits
''0123456789''
>>> set(string.digits)
{''7'', ''0'', ''2'', ''8'', ''6'', ''9'', ''1'', ''5'', ''4'', ''3''}
Los docs Python 3 son claros al respecto:
Un conjunto es una colección desordenada sin elementos duplicados.