2010-11-03 21 views
9

¿Cuál es la forma más fácil de crear un diccionario a partir de un iterable y asignarle un valor predeterminado? Probé:Crear un diccionario a partir de un iterable

>>> x = dict(zip(range(0, 10), range(0))) 

Pero eso no funciona ya que rango (0) no es un iterable como pensé que no sería

Entonces, ¿cómo hago para ella (pero traté de todos modos!) ? Si lo hago:

>>> x = dict(zip(range(0, 10), 0)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: zip argument #2 must support iteration 

Esto tampoco funciona. ¿Alguna sugerencia?

+0

No sabe lo suficiente sobre lo que usted está utilizando el diccionario, pero si el valor asociado nunca es realmente utilizado para cualquier cosa, considerar el uso de un pitón 'set' en lugar de un' dict'. Con eso, podrías decir 'x = set (range (10))'. – martineau

Respuesta

15

Necesita el método dict.fromkeys, que hace exactamente lo que desea.

A partir de los documentos:

fromkeys(...) 
    dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v. 
    v defaults to None. 

Así que lo que necesita es:

>>> x = dict.fromkeys(range(0, 10), 0) 
>>> x 
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0} 
+0

Gracias, funciona perfectamente y es fácil. – user225312

+0

Supongamos que quiero valores iguales a entradas de alguna lista, no un valor constante. ¿Cómo hacer? Algo como esto: '{0: y [0], 1: y [1], ...}' donde 'y' es una lista. – Sigur

2

Pulp Fiction da la forma práctica de hacerlo. Pero sólo por interés, puede hacer su trabajo de solución mediante el uso de itertools.repeat para una repetición 0.

x = dict(zip(range(0, 10), itertools.repeat(0))) 
+0

Esto también es bueno. – user225312

+0

+1 para esto. Esto es genial. – user225312

+0

En realidad no necesitas 'itertools' - esto será lo mismo usando' iter() 'built-in:' dict (zip (rango (0, 10), iter (lambda: 0, Ninguno))) 'o incluso solo si el valor predeterminado deseado es un int con un valor de' 0': 'dict (zip (rango (0, 10), iter (int, None)))'. – martineau

12

en Python 3, usted puede utilizar una comprensión dict.

>>> {i:0 for i in range(0,10)} 
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0} 

Afortunadamente, esto ha sido backported en python 2.7 por lo que también está disponible allí.

+0

No te he rechazado, pero en respuesta a tu pregunta, "No". – martineau

+0

(upvoted) sí lo hizo. bueno, la comprensión dict funciona en iteradores, pero sugiero cambiar "rango (0,10)" a "iter (xrange (0,10))" que es un iterador, para hacerlo "copiar y pegar- demostrable" –

1

Es posible que desee considerar el uso de la subclase defaultdict del módulo de la biblioteca estándar collections. Al usarlo, puede que ni siquiera necesite iterar a través de iterable ya que las claves asociadas con el valor predeterminado especificado se crearán cada vez que acceda a ellas por primera vez.

En el código de ejemplo siguiente he insertado un bucle for gratuito para forzar la creación de varios de ellos, de modo que la siguiente declaración de impresión tendrá algo que mostrar.

from collections import defaultdict 

dflt_dict = defaultdict(lambda:42) 

# depending on what you're doing this might not be necessary... 
for k in xrange(0,10): 
    dflt_dict[k] # accessing any key adds it with the specified default value 

print dflt_dict.items() 
# [(0, 42), (1, 42), (2, 42), (3, 42), ... (6, 42), (7, 42), (8, 42), (9, 42)] 
Cuestiones relacionadas