[英]python get pointer to an item in a nested dictionary/list combination based on a list of keys
I have a data structure that looks something like this:我有一个看起来像这样的数据结构:
someData = {"apple":{"taste":"not bad","colors":["red","yellow"]},
"banana":{"taste":"perfection","shape":"banana shaped"},
"some list":[6,5,3,2,4,6,7]}
and a list of keys which describes a path to some item in this structure以及描述此结构中某个项目的路径的键列表
someList = ["apple","colors",2]
I already have a function getPath(path)
(see below) that is supposed to return a pointer to the selected object.我已经有一个函数
getPath(path)
(见下文),它应该返回一个指向所选对象的指针。 It works fine for reading, but I get into trouble when trying to write它适合阅读,但我在尝试写作时遇到了麻烦
print(getPath(someList))
>> yellow
getPath(someList) = "green"
>> SyntaxError: can't assign to function call
a = getPath(someList)
a = "green"
print(getPath(someList))
>> "yellow"
Is there a way to make this work?有没有办法使这项工作? Maybe like this:
也许是这样的:
someFunc(someList, "green")
print(getPath(someList))
>> green
This question looks like this question , except that I want to write something to that item, and not just read it.这个问题看起来像这个问题,只是我想给那个项目写点东西,而不仅仅是阅读它。
My actual data can be seen here (I used json.loads() to parse the data).我的实际数据可以在这里看到(我使用 json.loads() 来解析数据)。 Note that I plan on adding stuff to this structure.
请注意,我计划向此结构添加内容。 I want a general approach to future proof the project.
我想要一个通用的方法来证明项目的未来。
My code:我的代码:
def getPath(path):
nowSelection = jsonData
for i in path:
nowSelection = nowSelection[i]
return nowSelection
The result you're getting from getPath()
is the immutable value from a dict or list.您从
getPath()
获得的结果是字典或列表中的不可变值。 This value does not even know it's stored in a dict or list, and there's nothing you can do to change it.该值甚至不知道它存储在字典或列表中,并且您无法更改它。 You have to change the dict/list itself.
您必须更改字典/列表本身。
Example:例子:
a = {'hello': [0, 1, 2], 'world': 2}
b = a['hello'][1]
b = 99 # a is completely unaffected by this
Compare with:与之比较:
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}
In your case, instead of following the path all the way to the value you want, go all the way except the last step, and then modify the dict/list you get from the penultimate step:在您的情况下,不是沿着路径一路找到您想要的值,而是一路走除了最后一步,然后修改您从倒数第二步获得的字典/列表:
getPath(["apple","colors",2]) = "green" # doesn't work
getPath(["apple","colors"])[2] = "green" # should work
You could cache your getPath
using custom caching function that allows you to manually populate saved cache.您可以使用自定义缓存功能缓存您的
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'
You can't literally do what you're trying to do.你不能从字面上做你想做的事。 I think the closest you could get is to pass the new value in, then manually reassign it within the function:
我认为你能得到的最接近的是传递新值,然后在函数中手动重新分配它:
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]}
I renamed it to setPath
to reflect its purpose better.我将其重命名为
setPath
以更好地反映其目的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.