簡體   English   中英

python根據鍵列表獲取指向嵌套字典/列表組合中項目的指針

[英]python get pointer to an item in a nested dictionary/list combination based on a list of keys

我有一個看起來像這樣的數據結構:

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

以及描述此結構中某個項目的路徑的鍵列表

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"

有沒有辦法使這項工作? 也許是這樣的:

someFunc(someList, "green")
print(getPath(someList))
>> green

這個問題看起來像這個問題,只是我想給那個項目寫點東西,而不僅僅是閱讀它。
我的實際數據可以在這里看到(我使用 json.loads() 來解析數據)。 請注意,我計划向此結構添加內容。 我想要一個通用的方法來證明項目的未來。

我的代碼:

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

您從getPath()獲得的結果是字典或列表中的不可變 該值甚至不知道它存儲在字典或列表中,並且您無法更改它。 您必須更改字典/列表本身。

例子:

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}

在您的情況下,不是沿着路徑一路找到您想要的值,而是一路走除了最后一步,然后修改您從倒數第二步獲得的字典/列表:

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

您可以使用自定義緩存功能緩存您的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'

你不能從字面上做你想做的事。 我認為你能得到的最接近的是傳遞新值,然后在函數中手動重新分配它:

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以更好地反映其目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM