我有一个外部主字典,我存储了一些值,还有一个辅助字典,我用它来迭代只有一些名称和我定义的第一个字典的值,看起来像这样:
main_dict = {
'colors': {
'foo': 'orange',
'bar': 'blue',
},
'fruits': {
'xyz': 'apple',
'abc': 'orange',
'qwe': 'strawberry'
}
}
secondary_dict = {
'word1': main_dict['colors']['bar'],
'word2': main_dict['fruits']['abc'],
'word3': main_dict['colors']['foo']
}
#A function that iterates the keys from secondary_dict, does something, and outputs a new dictionary:
new_dict = my_function(secondary_dict)
当我完成创建新词典时,我想将 BACK 写入原始词典的路径,用作辅助词典中的值,但我不知道如何这样做,所以在某种意义上它会像那种这样做:
secondary_dict = {
'word1': main_dict['colors']['bar'],
'word2': main_dict['fruits']['abc'],
'word3': main_dict['colors']['foo']
}
对此:
main_dict['colors']['bar'] = new_dict['word1'],
main_dict['fruits']['abc'] = new_dict['word2'],
main_dict['colors']['foo'] = new_dict['word3']
或(错误的)伪代码:
for key, path in secondary_dict.items():
path = new_dict[key]
我的第一个想法是,不是直接将路径存储在secondary_dict中,而是将存储为字符串,翻转字典并使用 eval()
进行迭代。但是,我使用eval()
收集的内容非常气馁,因为总会有更好的方式" ...
那么,有没有办法在不使用eval()
的情况下做我想做的事情?
(道歉,如果我很难理解我想说的话,我意识到这是一个相当具体的问题)
答案 0 :(得分:1)
以下是使用collections
模块的方法。
它有两个部分:一个Dict_Tree类,它“平坦化”对嵌套字典的访问。 (似乎与@Eugene K提议的非常类似。)
还有一个Proxy_Dict类。这将存储从简单键(如'word1')到完整键(如('colors','bar'))的映射,记录您分配给简单键的内容并将其写回主dict中。或仅在要求时。
import collections
class Dict_Tree(collections.UserDict):
def __init__(self, data=None):
super().__init__()
if not data is None:
self.data = data
def __getitem__(self, key):
node = self.data
for k in key:
node = node[k]
return node
def __setitem__(self, key, value):
node = self.data
for k in key[:-1]:
node = node.setdefault(k, {})
node[key[-1]] = value
class Proxy_Dict:
def __init__(self, master, delayed_writeback=True, **map):
self.delayed_writeback = delayed_writeback
self.master = master
if delayed_writeback:
self.front = collections.ChainMap({}, master)
else:
self.front = master
self.map = map
def __getitem__(self, key):
return self.front[self.map[key]]
def __setitem__(self, key, value):
self.front[self.map[key]] = value
def keys(self):
return self.map.keys()
def values(self):
return (self[k] for k in self.keys())
def items(self):
return ((k, self[k]) for k in self.keys())
def __iter__(self):
return iter(self.keys())
def writeback(self):
if self.delayed_writeback:
self.master.update(self.front.maps[0])
in_dict = {
'colors': {
'foo': 'orange',
'bar': 'blue',
},
'fruits': {
'xyz': 'apple',
'abc': 'orange',
'qwe': 'strawberry'
}
}
master = Dict_Tree(in_dict)
secondary = Proxy_Dict(master,
word1=('colors', 'bar'),
word2=('fruits', 'abc'),
word3=('colors', 'foo'))
secondary['word1'] = 'hello'
secondary['word2'] = 'world'
secondary['word3'] = '!'
secondary.writeback()