Ключи словаря как словарь

Вопрос

Как я могу использовать ключи словаря в качестве имени словаря и предшествующее имя в качестве ключа?

Вот аналогичный вопрос:
Пока я нашел только это двунаправленное отображение Python, который охватывает основную функцию двунаправленного отображения.

Я не хочу искать ключ для значений, но что-то вроде этого:

dict_one = { 'a': 123, 'b': 234 }
dict_two = { 'a': 567, 'b': 678 }
dict_one['a']
>> 123
dict_two['a']
>> 567
#... some magic (not simply defining a dict called 'a' though)
a['dict_one']
>> 123
a['dict_two']
>> 567

Ситуация

У меня есть несколько словарей, в которых хранятся константы для разных объектов. Каждый объект имеет одинаковые свойства (или они существуют для большинства объектов). Чтобы упростить вызов констант в циклах, были бы полезны оба описанных способа.


person gr4nt3d    schedule 19.04.2015    source источник
comment
Я бы предложил изменить ваш код до этого, чтобы он не приводил к этой проблеме в первую очередь meta.stackexchange.com/questions/66377/what-is-the-xy-problem   -  person sshashank124    schedule 19.04.2015
comment
Есть только 2 дикта? Если нет, то как вы планируете запоминать список переменных dict?   -  person Bhargav Rao    schedule 19.04.2015
comment
Вы можете создать функцию с именем (def a(dict_name):) и использовать eval(), чтобы предоставить вам доступ к объекту Dictionary на основе его имени. Этого было бы достаточно?   -  person Gord Thompson    schedule 19.04.2015
comment
@ sshashank124: Что бы вы посоветовали? - Я не могу представить лучшего способа хранения простых констант (см. Далее). На данный момент это в основном мысль, но да, вы правы, я прошу y. @BhargavRao: Нет, есть несколько словарей (2D-таблица, может быть расширена в будущем), содержащих физические константы. Вызов object['property'], а также property['object'] может облегчить жизнь функциям, работающим с несколькими константами одного и того же объекта, или наоборот. @GordThompson: Возможно, это решение, хотя оно изменило бы вызов на a('object'), не так ли? (Еще одна вещь, о которой нужно помнить)   -  person gr4nt3d    schedule 20.04.2015
comment
Да, использование функции приведет к вызову a('dict_one') вместо a['dict_one'], поэтому я разместил предложение как комментарий вместо ответа.   -  person Gord Thompson    schedule 20.04.2015


Ответы (2)


Для этого вы можете определить свой собственный класс, унаследованный от dict, и переопределить метод __getitem__. Но это решение также добавляет переменные через словарь globals, что не является рекомендуемой практикой, как упоминалось другими до меня.

class mdict(dict):
    def __getitem__(self, item):
        self.normal = dict(self)
        return self.normal[str(globals()[item])]

dict_one = {'a': 123, 'b': 234}
dict_two = {'a': 567, 'b': 678}

lst = [dict_one, dict_two]

for item in lst:
    for k, v in item.iteritems():
        dd = globals().setdefault(k, mdict())
        dd[str(item)] = v


>>> print a['dict_one']
123
>>> print b['dict_one']
234
>>> print a['dict_two']
567
>>> print b['dict_two']
678
person Saksham Varma    schedule 19.04.2015

Вам не следует использовать следующее решение, которое изменяет globals () (такого рода манипуляции со средой подвержены ошибкам, и их следует по возможности избегать!):

dict_one = { 'a': 123, 'b': 234 }
dict_two = { 'a': 567, 'b': 678 }

output = {}
for x in dict_one.keys():
    submap = output.get(x, {})
    submap["dict_one"] = dict_one[x]
    output[x] = submap

for x in dict_two.keys():
    submap = output.get(x, {})
    submap["dict_two"] = dict_two[x]
    output[x] = submap


# part 2
globs = globals()

for x in output:
    globs[x] = output[x]

print a['dict_two'] # 567

Что вам следует сделать, так это просто использовать output в качестве уровня абстракции (игнорируйте "часть 2" предыдущего фрагмента кода и вместо этого используйте):

print output['a']['dict_one'] #123
person Nir Alfasi    schedule 19.04.2015