print keys dictionaries dict create python dictionary set python-internals

keys - python dictionary of dictionaries



Dict/Set Parsing Consistencia de la Orden (1)

Contenedores que aceptan objetos hashable (como las claves de dict o los elementos set ). Como tal, un diccionario solo puede tener una clave con el valor 1 , 1.0 o True etc. (nota: algo simplificado: se permiten las colisiones de hash, pero estos valores se consideran iguales)

Mi pregunta es: ¿el orden de análisis está bien definido y el objeto resultante es predecible en todas las implementaciones? Por ejemplo, OSX Python 2.7.11 y 3.5.1 interpreta dict como:

>>> { True: ''a'', 1: ''b'', 1.0: ''c'', (1+0j): ''d'' } {True: ''d''}

En este caso, parece que la primera clave y el último valor se conservan.

Similar, en el caso del set :

>>> { True, 1, 1.0, (1+0j) } set([(1+0j)])

Aquí parece que el último artículo se conserva.

Pero (como se menciona en los comentarios):

>>> set([True, 1, 1.0]) set([True])

Ahora se conserva lo primero en lo iterable.

La documentación señala que el orden de los elementos (por ejemplo, en dict.items ) no está definido, sin embargo, mi pregunta se refiere al resultado de la construcción de dict o set objetos.


  • El error ahora está arreglado en las versiones recientes de python, como se explica en la respuesta de @jsf

dictionary-displays

Si se proporciona una secuencia separada por comas de pares clave / referencia, se evalúan de izquierda a derecha para definir las entradas del diccionario: cada objeto clave se utiliza como una clave en el diccionario para almacenar la referencia correspondiente. Esto significa que puede especificar la misma clave varias veces en la lista de claves / datos, y el último valor del diccionario para esa clave será el último.

Una comprensión de dictado, en contraste con la lista y configuración de comprensión, necesita dos expresiones separadas con dos puntos seguidos de las habituales cláusulas "para" y "si". Cuando se ejecuta la comprensión, la clave resultante y los elementos de valor se insertan en el nuevo diccionario en el orden en que se producen.

establecer pantallas

Una visualización de conjunto produce un nuevo objeto de conjunto mutable, el contenido se especifica mediante una secuencia de expresiones o una comprensión. Cuando se proporciona una lista de expresiones separadas por comas, sus elementos se evalúan de izquierda a derecha y se agregan al objeto establecido. Cuando se proporciona una comprensión, el conjunto se construye a partir de los elementos que resultan de la comprensión.

Hay una diferencia al llamar al constructor del conjunto o al utilizar una comprensión y el literal simple.

def f1(): return {x for x in [True, 1]} def f2(): return set([True, 1]) def f3(): return {True, 1} print(f1()) print(f2()) print(f3()) import dis print("f1") dis.dis(f1) print("f2") dis.dis(f2) print("f3") dis.dis(f3)

Salida:

{True} {True} {1}

La forma en que se crean influye en el resultado:

605 0 LOAD_CONST 1 (<code object <setcomp> at 0x7fd17dc9a270, file "/home/padraic/Dropbox/python/test.py", line 605>) 3 LOAD_CONST 2 (''f1.<locals>.<setcomp>'') 6 MAKE_FUNCTION 0 9 LOAD_CONST 3 (True) 12 LOAD_CONST 4 (1) 15 BUILD_LIST 2 18 GET_ITER 19 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 22 RETURN_VALUE f2 608 0 LOAD_GLOBAL 0 (set) 3 LOAD_CONST 1 (True) 6 LOAD_CONST 2 (1) 9 BUILD_LIST 2 12 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 15 RETURN_VALUE f3 611 0 LOAD_CONST 1 (True) 3 LOAD_CONST 2 (1) 6 BUILD_SET 2 9 RETURN_VALUE

Python solo ejecuta el bytecode BUILD_SET cuando pasas un literal puro separado por comas según:

Cuando se proporciona una lista de expresiones separadas por comas, sus elementos se evalúan de izquierda a derecha y se agregan al objeto establecido.

La línea para la comprensión:

Cuando se proporciona una comprensión, el conjunto se construye a partir de los elementos que resultan de la comprensión.

Entonces, gracias a Hamish que presenta un informe de error , de hecho se reduce al código de operación BUILD_SET según el comentario de Raymond Hettinger en el enlace.

TARGET(BUILD_SET) { PyObject *set = PySet_New(NULL); int err = 0; if (set == NULL) goto error; while (--oparg >= 0) { PyObject *item = POP(); if (err == 0) err = PySet_Add(set, item); Py_DECREF(item); } if (err != 0) { Py_DECREF(set); goto error; } PUSH(set); DISPATCH(); }