2017-08-15 50 views
0

想象如下嵌套JSON結構:最短方式典雅

node = 
{ 
    "0" : { 
    "param" : { 
     "filename" : "abc", 
     "delimiter" : "n" 
    }, 
    "function" : "do something" 
    }, 
    "1" : { 
    "param" : { 
     "filename" : "def", 
     "delimiter" : "n" 
    }, 
    "function" : "do something" 
    }, 
    "2" : { 
    "param" : { 
     "filename" : "ghi", 
     "delimiter" : "n" 
    }, 
    "function" : "do something" 
    } 
} 

我要替換所有的文件名的可變節點計算成文件名內。例如,我想將「0」,「1」和「2」中的所有文件名值替換爲「example.pdf」。

Python中最優雅的方式或最短的方法是什麼?

+0

'node = {new_key:v for _,v in node.items()}' – erip

+0

請先嚐試自己實現它。 – Maroun

+0

爲什麼不寫一個簡單的'for'循環?你試過了嗎? – timgeb

回答

1

怎麼樣的正則表達式?

In [29]: import re 

In [30]: json.loads(re.sub('(?<="filename": ")(.*?)(?=")', 'example.pdf', json.dumps(node))) 
Out[30]: 
{'0': {'function': 'do something', 
    'param': {'delimiter': 'n', 'filename': 'example.pdf'}}, 
'1': {'function': 'do something', 
    'param': {'delimiter': 'n', 'filename': 'example.pdf'}}, 
'2': {'function': 'do something', 
    'param': {'delimiter': 'n', 'filename': 'example.pdf'}}} 

這是行不通的,如果你不想更換實例。

+1

非常有創意,它還可以節省解析json的需求(+1) –

+0

@UriGoren是的......優點是您仍然可以支持使用子回調進行復雜替換...但不靈活,因爲你無法控制什麼被取代:) –

+1

創意,一條線和圓滑。確實很高雅! –

0

我不知道,如果它是優雅的,但我會做到這一點:

for k,v in node.items(): 
    v["param"]["filename"]="foo{}.pdf".format(k) 

的字典鍵/值迭代和「導航」的相關領域,並改變它(它涉及到的價值重點說明)

(重建使用字典解析字典似乎矯枉過正這裏)

0

如果你的鑰匙「PARAM」並不總是相同的,甚至是未知的,您可以使用此:

for k1, v1 in node.items(): 
    for k2, v2 in v1.items(): 
     if 'filename' in v2: 
      node[k1][k2]['filename'] = 'example.pdf' 
0

我會做遞歸

def override(node, key, val): 
    if type(node) != dict: 
     return node 
    new_node = dict() 
    for k, v in node.items(): 
      new_node[k] = override(v) if k != key else val 
    return new_node 

然後用

運行
node = override(node, "filename", "example.pdf") 

即使「文件名」嵌套得更深,它也可以工作