在Python中存储字典路径

Dom*_*ard 7 python dictionary

全新的python,让我说我有一个字典:

kidshair = {'allkids':{'child1':{'hair':'blonde'},
                      'child2':{'hair':'black'},
                      'child3':{'hair':'red'},
                      'child4':{'hair':'brown'}}}
Run Code Online (Sandbox Code Playgroud)

如果child3定期更改头发颜色,我可能想编写一个应用程序来加速数据维护.在这个例子中,我使用:

kidshair['allkids']['child3']['hair'] = ...
Run Code Online (Sandbox Code Playgroud)

有没有办法将此路径存储为变量,以便我可以在我的乐趣中访问它?明显

mypath = kidshair['allkids']['child3']['hair']
Run Code Online (Sandbox Code Playgroud)

导致mypath ='red'.是否有任何可能的方法来硬编码路径本身,所以我可以使用:

mypath = 'blue' 
Run Code Online (Sandbox Code Playgroud)

拒绝

kidshair['allkids']['child3']['hair'] = 'blue'
Run Code Online (Sandbox Code Playgroud)

非常感谢,ATfPT

Gar*_*tty 9

根据您的需要,最简单的选项可能是使用元组作为字典键而不是嵌套字典:

kidshair['allkids', 'child3', 'hair']
mypath = ('allkids', 'child3', 'hair')
kidshair[mypath]
Run Code Online (Sandbox Code Playgroud)

唯一的问题是你无法获得字典的一部分,因此,例如,你不能(轻松/有效地)访问所有要处理的内容'child3'.根据您的使用情况,这可能是也可能不适合您.

使用当前结构的替代方法是执行以下操作:

>>> from functools import partial
>>> test = {"a": {"b": {"c": 1}}}
>>> def itemsetter(item):
...     def f(name, value):
...         item[name] = value
...     return f
...
>>> mypath = partial(itemsetter(test["a"]["b"]), "c")
>>> mypath(2)
>>> test
{'a': {'b': {'c': 2}}}
Run Code Online (Sandbox Code Playgroud)

这里我们创建一个函数itemsetter(),它(在其中operator.itemgetter())给出了一个函数,用于设置给定字典中的相关键.然后functools.partial,我们使用我们想要预先填充的键来生成此函数的一个版本.它也不mypath = blue是,但它并不坏.

如果您不想打扰operator模块的某些内容,您可以简单地执行以下操作:

def dictsetter(item, name):
     def f(value):
         item[name] = value
     return f

mypath = dictsetter(test["a"]["b"], "c")

mypath(2)
Run Code Online (Sandbox Code Playgroud)


Joe*_*ett 7

您可以创建一组函数来访问给定字典的"路径":

def pathGet(dictionary, path):
    for item in path.split("/"):
        dictionary = dictionary[item]
    return dictionary

def pathSet(dictionary, path, setItem):
    path = path.split("/")
    key = path[-1]
    dictionary = pathGet(dictionary, "/".join(path[:-1]))
    dictionary[key] = setItem
Run Code Online (Sandbox Code Playgroud)

用法:

>>> pathGet(kidshair, "allkids/child1/hair")
'blonde'
>>> pathSet(kidshair, "allkids/child1/hair", "blue")
>>> kidshair['allkids']['child1']
{'hair': 'blue'}
Run Code Online (Sandbox Code Playgroud)