Разрушать-связывать содержимое словаря

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

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)