簡體   English   中英

Python如何通過鏈接'key'來訪問特定的json字典值

[英]Python how to access specific json dictionary value by chaining the 'key'

如果我有以下 Json:

{
"a": {
       "b" : {
               "c" : "value"
             }
      }
}

這是通過 json.load() 加載到我的對象 (obj) 中的

然后我有另一個變量是

path = "a.b.c"

要訪問 json 中 'c' 的值,我通常會這樣做:

obj["a"]["b"]["c"]

但是我想利用“路徑”變量,並做這樣的事情:

obj[path]

這可能嗎? 如何實現

您可以拆分點上的路徑並使用reduce來獲取嵌套值。

from functools import reduce
d = {'a':{'b':{'c':'value'}}}
path = "a.b.c"
val = reduce(lambda o, k: o[k], path.split("."), d)
print(val)

演示

您可以編寫一個將 JSON 數據和路徑都作為參數的函數。 它可以遍歷路徑中的每個鍵(由.分隔)並以這種方式遍歷 JSON。

def json_from_path(data: dict, path: str):
    for key in path.split('.'):
        data = data[key]
    return data

可以使用operator.getitemfunctools.reduce的組合來做到這一點:

>>> from functools import reduce
>>> from operator import getitem
>>> dct = {'a': {'b': {'c': 'value'}}}
>>> reduce(getitem, "a.b.c".split("."), dct)
'value'

它的工作方式是,reduce 最初將使用dct調用getitem"abc".split()"a" ,然后在下一次迭代中將其結果傳遞給getitem ,但這次使用"b"等等……

>>> getitem(dct, "a")
{'b': {'c': 'value'}}
>>> getitem(getitem(dct, "a"), "b")
{'c': 'value'}
>>> getitem(getitem(getitem(dct, "a"), "b"), "c")
'value'

getitem本身的工作方式如下:

>>> getitem?
Signature: getitem(a, b, /)
Docstring: Same as a[b].
Type:      builtin_function_or_method

它是第三方安裝,但jq允許您使用jq過濾器語言遍歷數據結構。

>>> import jq
>>> d = {"a": {"b": {"c": "value"}}}
>>> jq.compile(".a.b.c").input(d).first()
'value'

(請注意, .必須在路徑中的每個鍵之前,而不是簡單地分隔鍵。)

這可能有點超出問題的范圍,但您始終可以將dict類型子類化並覆蓋__getitem__方法以獲得您正在尋找的結果。

這是您可以使用 OP 使用的語法實際實現 OP 要求的結果的方式。

例如:

class Dict(dict):
    def __getitem__(self, val):
        try: return super().__getitem__(val)
        except KeyError:
            keys = val.split(".")
            value = super().__getitem__(keys[0])
            d = Dict(value)
            return d['.'.join(keys[1:])]

然后就這么簡單:

path = 'a.b.c'
obj = Dict({"a": {"b" : {"c" : "value"}}})

result = obj[path]

print(result)

輸出

value

暫無
暫無

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

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