Разрушать-связывать содержимое словаря - PullRequest
34 голосов
/ 02 июня 2010

Я пытаюсь «деструктурировать» словарь и связать значения с именами переменных после их ключей. Что-то вроде

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

Но поскольку словари не упорядочены, нет гарантии, что params.values() вернет значения в порядке (a, b). Есть ли хороший способ сделать это?

Ответы [ 9 ]

25 голосов
/ 13 июня 2013

Один из способов сделать это с меньшим количеством повторений, чем предложено Йохеном, - использовать вспомогательную функцию. Это дает гибкость в перечислении имен ваших переменных в любом порядке и деструктурирует только подмножество того, что находится в диктанте:

pluck = lambda dict, *args: (dict[arg] for arg in args)

things = {'blah': 'bleh', 'foo': 'bar'}
foo, blah = pluck(things, 'foo', 'blah')

Кроме того, вместо OrderedDict Хоакина вы можете отсортировать ключи и получить значения. Единственное, что вам нужно, это указать имена переменных в алфавитном порядке и деструктурировать все в слове:

sorted_vals = lambda dict: (t[1] for t in sorted(dict.items()))

things = {'foo': 'bar', 'blah': 'bleh'}
blah, foo = sorted_vals(things)
17 голосов
/ 29 августа 2018
from operator import itemgetter

params = {'a': 1, 'b': 2}

a, b = itemgetter('a', 'b')(params)

Вместо сложных лямбда-функций или словарного понимания можно использовать встроенную библиотеку.

13 голосов
/ 18 февраля 2015

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
8 голосов
/ 02 июня 2010

Может быть, вы действительно хотите сделать что-то подобное?

def some_func(a, b):
  print a,b

params = {'a':1,'b':2}

some_func(**params) # equiv to some_func(a=1, b=2)
7 голосов
/ 02 июня 2010

Если вы боитесь проблем, связанных с использованием словаря местных жителей, и предпочитаете следовать своей оригинальной стратегии, то Упорядоченные словари из python 2.7 и 3.1 collection.OrderedDicts позволяют вам восстановить элементы словаря в том порядке, в котором они были впервые вставлены

4 голосов
/ 19 декабря 2018

Вот еще один способ сделать это аналогично тому, как деструктурирующее назначение работает в 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}

Полезно для исключения ненужных ключей из словаря.

Надеюсь, это поможет.

3 голосов
/ 30 июля 2018

попробуйте

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

результат:

a == 'Apple'
b == 'Banana'
c == 'Carrot'
2 голосов
/ 02 июня 2010

Ну, если вы хотите это в классе, вы всегда можете сделать это:

class AttributeDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttributeDict, self).__init__(*args, **kwargs)
        self.__dict__.update(self)

d = AttributeDict(a=1, b=2)
0 голосов
/ 02 июня 2010

Не знаю, хороший ли это стиль, но

locals().update(params)

сделает свое дело. Затем у вас есть a, b и все, что было в вашем params дикте, доступное как соответствующие локальные переменные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...