python根据键列表获取嵌套字典/列表组合中的项的指针

python根据键列表获取嵌套字典/列表组合中的项的指针,python,python-3.x,list,dictionary,pointers,Python,Python 3.x,List,Dictionary,Pointers,我的数据结构如下所示: someData = {"apple":{"taste":"not bad","colors":["red","yellow"]}, "banana":{"taste":"perfection","shape":"banana shaped"}, "some list":[6,5,3,2,4,6,7]} someFunc(someList, "green") print(getPath(someList)) >> green 以及一个键列表,其中描述了此结

我的数据结构如下所示:

someData = {"apple":{"taste":"not bad","colors":["red","yellow"]},
"banana":{"taste":"perfection","shape":"banana shaped"},
"some list":[6,5,3,2,4,6,7]}
someFunc(someList, "green")
print(getPath(someList))
>> green
以及一个键列表,其中描述了此结构中某个项的路径

someList = ["apple","colors",2]
我已经有了一个函数
getPath(path)
(见下文),它应该返回指向所选对象的指针。它对阅读很有效,但我在尝试写作时遇到了麻烦

print(getPath(someList))
>> yellow

getPath(someList) = "green"
>> SyntaxError: can't assign to function call

a = getPath(someList)
a = "green"
print(getPath(someList))
>> "yellow"
有没有办法让这一切顺利进行?也许是这样:

someData = {"apple":{"taste":"not bad","colors":["red","yellow"]},
"banana":{"taste":"perfection","shape":"banana shaped"},
"some list":[6,5,3,2,4,6,7]}
someFunc(someList, "green")
print(getPath(someList))
>> green
这个问题看起来像是,除了我想写一些东西到那个项目,而不是仅仅读它。
可以看到我的实际数据(我使用json.loads()解析数据)。请注意,我计划将内容添加到此结构中。我想要一个通用的方法来证明未来的项目

我的代码:

def getPath(path):
    nowSelection = jsonData
    for i in path:
        nowSelection = nowSelection[i]
    return nowSelection

您可以使用自定义缓存功能来缓存
getPath
,该功能允许您手动填充保存的缓存

from functools import wraps

def cached(func):
    func.cache = {}
    @wraps(func)
    def wrapper(*args):
        try:
            return func.cache[args]
        except KeyError:
            func.cache[args] = result = func(*args)
            return result   
    return wrapper


@cached
def getPath(l):
    ...

getPath.cache[(someList, )] = 'green'
getPath(someList)  # -> 'green'

getPath()
得到的结果是dict或list中的不可变值。这个值甚至不知道它存储在dict或list中,您也无法更改它。您必须更改目录/列表本身

例如:

a = {'hello': [0, 1, 2], 'world': 2}
b = a['hello'][1]
b = 99             # a is completely unaffected by this
与之相比:

a = {'hello': [0, 1, 2], 'world': 2}
b = a['hello']     # b is a list, which you can change
b[1] = 99          # now a is {'hello': [0, 99, 2], 'world': 2}
在您的情况下,与其沿着路径一直走到您想要的值,不如一直走到最后一步,然后修改倒数第二步得到的dict/list:

getPath(["apple","colors",2]) = "green"  # doesn't work
getPath(["apple","colors"])[2] = "green" # should work

你无法真正做到你想做的事。我认为最接近的方法是传入新值,然后在函数中手动重新分配它:

someData = {"apple":{"taste":"not bad","colors":["red","yellow"]}, "banana":{"taste":"perfection","shape":"banana shaped"}, "some list":[6,5,3,2,4,6,7]}

def setPath(path, newElement):
    nowSelection = someData
    for i in path[:-1]:  # Remove the last element of the path
        nowSelection = nowSelection[i]

    nowSelection[path[-1]] = newElement  # Then use the last element here to do a reassignment

someList = ["apple","colors",1]

setPath(someList, "green")

print(someData) 

{'apple': {'taste': 'not bad', 'colors': ['red', 'green']}, 'banana': {'taste': 'perfection', 'shape': 'banana shaped'}, 'some list': [6, 5, 3, 2, 4, 6, 7]}
我将其重命名为
setPath
,以更好地反映其用途