【问题标题】:Python 3.6 nested dictionary dynamic updatePython 3.6 嵌套字典动态更新
【发布时间】:2018-09-15 12:07:12
【问题描述】:

我有一个类似如下的文件:

HP;1<br/>
MN;stringval<br/>
IS/VD1;32.00<br/>
IS/HD1;1.34<br/>
IS/E/ID;362.0000000<br/>
IS/OLVD;0.0000000<br/>
ISN/I/HFD;3283.8999023<br/>
D1/I/MF;7.3059464<br/>
D1/I/P;32.0388412<br/>
D1/E/E;2778.4829102<br/>
D1/S1/SB/I/P;32.0388412<br/>
EN;5145<br/>

在“;”之后有我想放入字典的值。

/ 后面的每个单词都是一个键。

我的最终目标是拥有以下字典:

{"HP":1.0,"MN":'stringval',"IS":{"VD1":32.00,"HD1":1.34,"E":{"ID":362.0000000},"OLVD":0.0000000},"ISN":{"I":{"HFD":3283.8999023}},"D1":{"I":{"MF":7.3059464,"P":32.03884},"E":{"E":2778.4829102},"S1":{"SB":{"I":{"P":32.0388412}}}},"EN":5145}

我不知道最终字典的最大层数。

我尝试了以下代码:

fid = open(myfile,mode='r')
content=fid.readlines()
content = [x.replace(' ','').strip() for x in content]
outdata = dict()
for i in content:

    dict_struct = i.split(';')[0]
    val = i.split(';')[-1]
    n_lev = dict_struct.count('/')
    test2 = '{"' + dict_struct.replace('/', '":{"') + '":' + val + '}' * (n_lev + 1)

    try:
        outdata.update(eval(test2))
        print(test2)
    except:
        test2 = '{"' + dict_struct.replace('/', '":{"') + '":"' + val + '"' + '}' * (n_lev + 1)
        print(test2)
        outdata.update(eval(test2))

此代码不起作用,因为update() 实际上覆盖了一些输入;这是输出:

{"HP": 1, "MN": "stringval", "IS": {"OLVD": 0.0}, "ISN": {"I": {"HFD": 3283.8999023}}, "D1": {"S1": {"SB": {"I": {"P": 32.0388412}}}}, "EN": 5145}

你能给我一些提示吗?

【问题讨论】:

    标签: python dictionary nested


    【解决方案1】:

    您可以使用字典结构构建一棵树

    这里是我的解决方案

    import json,sys
    
    
    def update(k,v):
        d = {}
        d[k]=v
        return d 
    
    
    
    def processRow(row):
        value = row.split(';', 2)
        #print(value)
        if len(value)<=1:
            return 
        keys = value[0].split('/')
        v=value[1]
    
        try:
            v=[float(v)]
        except:
            v=[v]
    
        for i, e in reversed(list(enumerate(keys))):
            v = update(e,v)
    
        return v
    
    def updateTree(dic, tree):
        #print("IN %s -> OUT %s" % (dic, json.dumps(tree, indent = 4)))
        #print()
        for key in dic:
            value=dic[key]
            subtree = tree.get(key)
    
            if subtree and isinstance(subtree, dict):
                updateTree(value,subtree)
            elif subtree and isinstance(subtree, list) and isinstance(value, list):
                subtree.extend(value)
            elif not(subtree):
                tree.update(dic)
            else:
                sys.stderr.write ("ERROR: incoherent data type %s vs %s" % (dic, json.dumps(tree, indent = 4)))
    
    
    txt = "HP;1\nMN;stringval\nIS/VD1;32.00\nIS/HD1;1.34\nIS/E/ID;362.0000000\n"
    rows = txt.split('\n')
    x = []
    
    t={}
    for row in rows:
        v = processRow(row)
        if (v):
            updateTree(v,t)
    
    print (json.dumps(t, indent = 4))
    

    结果是

    {
        "HP": [
            1.0
        ],
        "MN": [
            "stringval"
        ],
        "IS": {
            "VD1": [
                32.0
            ],
            "HD1": [
                1.34
            ],
            "E": {
                "ID": [
                    362.0
                ]
            }
        } }
    

    【讨论】:

      【解决方案2】:

      你需要做一些基本的字符串解析来构建嵌套字典:

      >>> S = "D1/S1/SB/I/P;32.0388412"
      >>> D = {}
      >>> parts1 = S.split(';', 2)
      >>> parts2 = parts1[0].split('/')
      >>> D2 = D
      >>> for i, e in enumerate(parts2):
      ...     if i == len(parts2) - 1:
      ...         D2[e] = parts1[1]
      ...     else:
      ...         D3 = {}
      ...         D2[e] = D3
      ...         D2 = D3
      ... 
      >>> D
      {'D1': {'S1': {'SB': {'I': {'P': '32.0388412'}}}}}
      

      【讨论】:

      • 您好 vz0,您的解决方案适用于单个字符串。我试图将所有内容都放在一个 for 循环中,但它不起作用(for S in content: ...)。非常感谢您的帮助!
      猜你喜欢
      • 2019-12-04
      • 2018-06-02
      • 2021-06-21
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      • 2022-01-15
      • 1970-01-01
      相关资源
      最近更新 更多