que - Orden de iteración de conjuntos en Python
para que sirven los conjuntos en python (5)
No fue solo una coincidencia que salieran igual: la implementación resulta ser determinista, por lo que crear el mismo conjunto produce dos veces el mismo orden. Pero Python no garantiza eso.
Si creas el mismo conjunto de dos maneras diferentes:
n = set("abc")
print n
m = set("kabc")
m.remove("k")
print m
... puedes obtener diferentes pedidos:
set([''a'', ''c'', ''b''])
set([''a'', ''b'', ''c''])
Si tengo dos conjuntos idénticos, lo que significa que a == b
me da True
, ¿tendrán el mismo orden de iteración? Lo probé, y funciona:
>>> foo = set("abc")
>>> bar = set("abc")
>>> zip(foo, bar)
[(''a'', ''a''), (''c'', ''c''), (''b'', ''b'')]
Mi pregunta es: ¿tuve suerte o está garantizado este comportamiento?
No.:
>>> class MyStr( str ):
... def __hash__( self ):
... return 0
...
>>> a = MyStr( "a" )
>>> b = MyStr( "b" )
>>> c = MyStr( "c" )
>>> foo = { a, b, c }
>>> foo
{''c'', ''b'', ''a''}
>>> bar = { b, a, c }
>>> foo is bar
False
>>> foo == bar
True
>>> list( zip( foo, bar ) )
[(''c'', ''c''), (''b'', ''a''), (''a'', ''b'')]
PD: No tengo idea de si la anulación de __hash__
es necesaria. Acabo de intentar algo que pensé que rompería esto, y lo hizo.
Sí, tuviste suerte. Ver por ejemplo:
import random
r = [random.randint(1,10000) for i in range(20)]
foo = set(r)
r.sort(key=lambda _: random.randint(1,10000))
bar = set(r)
print foo==bar
print zip(foo, bar)
Lo que me dio el resultado:
True
[(3234, 3234), (9393, 9393), (9361, 1097), (1097, 5994), (5994, 2044), (1614, 1614), (6074, 4377), (4377, 9361), (5202, 5202), (2355, 2355), (1012, 1012), (7349, 7349), (6198, 6198), (8489, 8489), (7929, 7929), (6556, 6074), (6971, 6971), (2044, 6556), (7133, 7133), (383, 383)]
Tuviste suerte, el pedido no está garantizado. Lo único que está garantizado es que los conjuntos tendrán los mismos elementos.
Si necesita algún tipo de previsibilidad, puede ordenarlos así: zip(sorted(foo), sorted(bar))
.
Yo diría que tienes suerte. Sin embargo, también podría ser que, dado que los elementos del conjunto eran los mismos, se almacenaron en el mismo orden. Este comportamiento no es algo en lo que quieras confiar.