Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 设置一个字典中的值,其中包含指向另一个字典的路径_Python_Python 3.x - Fatal编程技术网

Python 设置一个字典中的值,其中包含指向另一个字典的路径

Python 设置一个字典中的值,其中包含指向另一个字典的路径,python,python-3.x,Python,Python 3.x,我有一个外部主字典,其中存储了一些值,还有一个辅助字典,我使用它只对第一个字典的一些名称和定义的值进行迭代,如下所示: main_dict = { 'colors': { 'foo': 'orange', 'bar': 'blue', }, 'fruits': { 'xyz': 'apple', 'abc': 'orange', 'qwe': 'strawberry' } } se

我有一个外部主字典,其中存储了一些值,还有一个辅助字典,我使用它只对第一个字典的一些名称和定义的值进行迭代,如下所示:

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)
from collections import reduce


class MyWrappedDict:
""" Just an example
"""
    def __init__(self, dict_source):
        self._dict_source = dict_source

    def __getitem__(self, key):
        keys = key.split('.')
        return reduce(dict.get, keys, self._dict_source)

    def __setitem__(self, key, value):
        keys = key.split('.')
        last_key = keys[-1]
        reduce(dict.get, keys[:-1], self._dict_source)[last_key] = value
# usage
d = MyWrappedDict(main_dict)
print(d['colors.bar']) # -> 'blue'
d['colors.bar'] = 'Text'

secondary_dict = {
    'word1': 'colors.bar',
    'word2': 'fruits.abc',
    'word3': 'colors.foo'
}
当我创建完新词典后,我想将写回作为辅助词典中的值的原始词典的路径,但我不知道如何做,所以从某种意义上说,这有点像这样做:

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]
我最初的想法之一是,不直接将路径存储在二级目录中,而是将路径存储为字符串,翻转字典并使用
eval()进行迭代。但是从我所能收集到的信息来看,使用
eval()
是非常不鼓励的,因为总有“更好的方法”

那么,有没有办法不用
eval()
就完成我想做的事情呢?


(如果很难理解我想说的话,我表示歉意,我意识到这是一个相当特殊的问题)

如果您将使用类似路径的键,您可以编写一个帮助器类,如下所示:

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)
from collections import reduce


class MyWrappedDict:
""" Just an example
"""
    def __init__(self, dict_source):
        self._dict_source = dict_source

    def __getitem__(self, key):
        keys = key.split('.')
        return reduce(dict.get, keys, self._dict_source)

    def __setitem__(self, key, value):
        keys = key.split('.')
        last_key = keys[-1]
        reduce(dict.get, keys[:-1], self._dict_source)[last_key] = value
# usage
d = MyWrappedDict(main_dict)
print(d['colors.bar']) # -> 'blue'
d['colors.bar'] = 'Text'

secondary_dict = {
    'word1': 'colors.bar',
    'word2': 'fruits.abc',
    'word3': 'colors.foo'
}

下面是一种使用
集合
模块的方法

它有两个部分:一个Dict_树类,用于“展平”对嵌套Dict的访问(似乎与@Eugene K的建议非常相似)

和一个代理Dict类。它存储从简单键(如“word1”)到完整键(如(“颜色”、“条形”)的映射,记录分配给简单键的内容,并动态或仅在请求时将其写回主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()

reduce(+1)的用法很好,不过我认为应该导入它。有没有办法将
master
变量转换回标准字典?因为我正在从文件中读取
,我希望能够将其写回文件。@C1N14
master
引用了
中的数据。母版的更改也会更改目录中的
。试着给
master
分配一些内容,然后查看dict
中的
。@我不是100%确定我明白你想做什么。你的意思是从你在问题中使用的
secondary
形式到我的形式?这会很困难,因为表单没有存储实际路径,对吗?可能需要的是处理源代码,因为它确实包含路径。对不起,我当时有点匆忙,我甚至不知道我写了什么lol。我需要的是一种方法来迭代
代理中已经设置的键,而不是设置它们。类似于:
对于k,v在secondary.items()中:
,因为我使用键的名称。除此之外,这个答案是正确的perfect@C1N14我还是不太明白。你是说你有一本字典,上面有“word1”、“word2”等键,你想把它的值输入到dict['colors']['bar']
中的[u dict['fruits']['abc']
中吗。?