Разрушать-связывать содержимое словаря
Я пытаюсь "деструктурировать" словарь и связать значения с именами переменных после их ключей. Что-то вроде
params = {'a':1,'b':2}
a,b = params.values()
Но поскольку словари не упорядочены, нет гарантии, что params.values()
будет возвращать значения в порядке (a, b)
. Есть хороший способ сделать это?
Ответы
Ответ 1
Если вы боитесь проблем, связанных с использованием словаря локальных жителей, и предпочитаете следовать своей оригинальной стратегии, то Упорядоченные словари из python 2.7 и 3.1 collection.OrderedDicts позволяют восстанавливать элементы словаря в порядке в котором они были впервые вставлены
Ответ 2
from operator import itemgetter
params = {'a': 1, 'b': 2}
a, b = itemgetter('a', 'b')(params)
Вместо сложных лямбда-функций или словарного понимания можно использовать встроенную библиотеку.
Ответ 3
Один из способов сделать это с меньшим повторением, чем предложение Йохана, - это вспомогательная функция. Это дает возможность перечислять имена переменных в любом порядке и только разрушать подмножество того, что находится в dict:
pluck = lambda dict, *args: (dict[arg] for arg in args)
things = {'blah': 'bleh', 'foo': 'bar'}
foo, blah = pluck(things, 'foo', 'blah')
Кроме того, вместо joaquin OrderedDict вы можете отсортировать ключи и получить значения. Единственные уловы - вам нужно указать имена переменных в алфавитном порядке и разрушить все в dict:
sorted_vals = lambda dict: (t[1] for t in sorted(dict.items()))
things = {'foo': 'bar', 'blah': 'bleh'}
blah, foo = sorted_vals(things)
Ответ 4
Python способен только "разрушать" последовательности, а не словари. Итак, чтобы написать то, что вы хотите, вам нужно будет отобразить необходимые записи в правильную последовательность. Что касается меня самого, ближайший матч, который я смог найти, это (не очень сексуальный):
a,b = [d[k] for k in ('a','b')]
Это также работает с генераторами:
a,b = (d[k] for k in ('a','b'))
Вот полный пример:
>>> 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
Ответ 5
Может быть, вы действительно хотите сделать что-то вроде этого?
def some_func(a, b):
print a,b
params = {'a':1,'b':2}
some_func(**params) # equiv to some_func(a=1, b=2)
Ответ 6
Вот еще один способ сделать это аналогично тому, как назначение деструктуризации работает в JS:
params = {'b': 2, 'a': 1}
a, b, rest = (lambda a, b, **rest: (a, b, rest))(**params)
Мы распаковали словарь параметров в ключевые значения (используя **) (как в ответе Йохена), затем мы взяли эти значения в лямбда-сигнатуре и присвоили их в соответствии с именем ключа - а здесь бонус - мы также получите словарь того, чего нет в лямбда-сигнатуре, так что если у вас есть:
params = {'b': 2, 'a': 1, 'c': 3}
a, b, rest = (lambda a, b, **rest: (a, b, rest))(**params)
После применения лямбды переменная rest будет содержать: {'c': 3}
Полезно для исключения ненужных ключей из словаря.
Надеюсь это поможет.
Ответ 7
попробуй это
d = {'a':'Apple', 'b':'Banana','c':'Carrot'}
a,b,c = [d[k] for k in ('a', 'b','c')]
результат:
a == 'Apple'
b == 'Banana'
c == 'Carrot'
Ответ 8
Ну, если вы хотите этого в классе, вы всегда можете это сделать:
class AttributeDict(dict):
def __init__(self, *args, **kwargs):
super(AttributeDict, self).__init__(*args, **kwargs)
self.__dict__.update(self)
d = AttributeDict(a=1, b=2)
Ответ 9
Я не знаю, хороший ли стиль, но
locals().update(params)
сделает трюк. Затем у вас есть a
, b
и все, что было в вашем params
dict, доступном как соответствующие локальные переменные.
Ответ 10
Основываясь на ответе @ShawnFumo, я придумал следующее:
def destruct(dict): return (t[1] for t in sorted(dict.items()))
d = {'b': 'Banana', 'c': 'Carrot', 'a': 'Apple' }
a, b, c = destruct(d)
(обратите внимание на порядок элементов в dict)