2012-03-24 19 views
10

Digamos que tiene un conjunto:Conjunto estallar (Python)

foo = {1, 2, 3, 4, 5} 

En el libro que estoy leyendo actualmente, Pro Python, se dice que el uso de foo.pop() aparecerá un número arbitrario de esa selección. PERO ... Cuando lo intento, es pops 1, then 2, then 3... ¿Lo hace arbitrariamente, o es solo una coincidencia?

+0

Esto tiene que ver con la función hash que utiliza un conjunto para mapear su contenido a ubicaciones en la memoria. Intenta hacer 'hash()' en diferentes tipos de datos y ver qué números obtienes. El número arbritrary salido de un conjunto _will_ será el _next_ elemento en el conjunto. Da la casualidad de que la "orden" en que el conjunto almacena los datos puede no ser necesariamente ordenada por lo que a usted respecta. En este ejemplo, el orden en que coinciden los elementos coincide con el orden en que se almacena/recupera el hashmap. –

+0

Encontré lo mismo hoy y quiero subir tu pregunta –

Respuesta

16

La razón por la que dice que es arbitraria es porque no hay garantía sobre el orden en que saldrá. Como acaba de crear el conjunto, puede almacenar los elementos en un orden "bueno" y, por lo tanto, .pop() pasa a devolverlos en ese orden, pero si cambiara el conjunto, es posible que no continúe.

Ejemplo:

>>> foo = set() 
>>> foo.add(-3) 
>>> foo.add(-1) 
>>> foo.add(2) 
>>> foo.pop() 
2 
>>> foo.pop() 
-3 
14

Set y los diccionarios se implementan utilizando tablas hash. Son colecciones desordenadas, lo que significa que no tienen un orden garantizado.

El orden que está viendo es un detalle de implementación no garantizado. En CPython, el valor hash para un entero es el número entero en sí:

>>> [hash(i) for i in range(10)] 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Ese detalle de implementación hace que los números enteros que aparecen ordenados en su conjunto. Otros conjuntos se ordenan a medias, {5, 6, 7, 8, 9} aparece como set([8, 9, 5, 6, 7]).

En contraste, otros tipos de datos como str tienen diferentes funciones hash y parecerán más codificadas. Por ejemplo:

# Example of scrambling str objects in a 64-bit build 
>>> {'red', 'green', 'blue'} 
set(['blue', 'green', 'red']) 

El método set.pop aparece fuera de entradas de izquierda a derecha. Eso también es un detalle de implementación no garantizado.

La respuesta breve a su pregunta es Sí, el orden es arbitrario pero no, lo que usted vio no fue sólo una coincidencia, sino que fue un detalle de implementación no garantizado.

Espero que esto aclare en marcha el misterio para usted :-)

Cuestiones relacionadas