Destructurar-enlazar los contenidos del diccionario.

Estoy tratando de ‘destruir’ un diccionario y asociar valores con nombres de variables después de sus claves. Algo como

params = {'a':1,'b':2} a,b = params.values() 

Pero como los diccionarios no están ordenados, no hay garantía de que params.values() devuelva valores en el orden de (a, b) . ¿Hay una buena manera de hacer esto?

Si le temen los problemas relacionados con el uso del diccionario local y prefiere seguir su estrategia original, los Diccionarios Ordenados de las colecciones Python 2.7 y 3.1. LosDictos de Orden le permiten recuperar los elementos del diccionario en el orden en que se insertaron por primera vez.

Una forma de hacer esto con menos repetición que la sugerencia de Jochen es con una función de ayuda. Esto le da la flexibilidad de enumerar los nombres de sus variables en cualquier orden y solo destruir un subconjunto de lo que está en el dict:

 pluck = lambda dict, *args: (dict[arg] for arg in args) things = {'blah': 'bleh', 'foo': 'bar'} foo, blah = pluck(things, 'foo', 'blah') 

Además, en lugar de OrderedDict de Joaquín, puede ordenar las claves y obtener los valores. Las únicas capturas son las que necesita para especificar los nombres de sus variables en orden alfabético y desestructurar todo en el dictado:

 sorted_vals = lambda dict: (t[1] for t in sorted(dict.items())) things = {'foo': 'bar', 'blah': 'bleh'} blah, foo = sorted_vals(things) 

Python solo es capaz de “destruir” secuencias, no diccionarios. Por lo tanto, para escribir lo que desea, deberá asignar las entradas necesarias a una secuencia adecuada. En cuanto a mí, la coincidencia más cercana que pude encontrar es la (no muy sexy):

 a,b = [d[k] for k in ('a','b')] 

Esto funciona también con generadores:

 a,b = (d[k] for k in ('a','b')) 

Aquí hay un ejemplo completo:

 >>> d = dict(a=1,b=2,c=3) >>> d {'a': 1, 'c': 3, 'b': 2} >>> a, b = [d[k] for k in ('a','b')] >>> a 1 >>> b 2 >>> a, b = (d[k] for k in ('a','b')) >>> a 1 >>> b 2 

Tal vez realmente quieres hacer algo como esto?

 def some_func(a, b): print a,b params = {'a':1,'b':2} some_func(**params) # equiv to some_func(a=1, b=2) 
 from operator import itemgetter params = {'a': 1, 'b': 2} a, b = itemgetter('a', 'b')(params) 

En lugar de las funciones lambda elaboradas o la comprensión del diccionario, también se puede utilizar una biblioteca integrada.

prueba esto

 d = {'a':'Apple', 'b':'Banana','c':'Carrot'} a,b,c = [d[k] for k in ('a', 'b','c')] 

resultado:

 a == 'Apple' b == 'Banana' c == 'Carrot' 

Bueno, si quieres estos en una clase siempre puedes hacer esto:

 class AttributeDict(dict): def __init__(self, *args, **kwargs): super(AttributeDict, self).__init__(*args, **kwargs) self.__dict__.update(self) d = AttributeDict(a=1, b=2) 

Aquí hay otra forma de hacerlo de manera similar a cómo funciona una asignación de desestructuración en JS:

 params = {'b': 2, 'a': 1} a, b, rest = (lambda a, b, **rest: (a, b, rest))(**params) 

Lo que hicimos fue descomprimir el diccionario de parámetros en valores clave (usando **) (como en la respuesta de Jochen ), luego tomamos esos valores en la firma lambda y los asignamos de acuerdo con el nombre de la clave, y aquí hay un bono: también obtenga un diccionario de lo que no está en la firma de la lambda, así que si tuviera:

 params = {'b': 2, 'a': 1, 'c': 3} a, b, rest = (lambda a, b, **rest: (a, b, rest))(**params) 

Después de que se haya aplicado la lambda, la variable de descanso ahora contendrá: {‘c’: 3}

Útil para omitir claves innecesarias de un diccionario.

Espero que esto ayude.

No sé si es buen estilo, pero

locals().update(params)

Hará el truco. Luego, tiene a , b y lo que haya en sus params disponibles como variables locales correspondientes.