【问题标题】:Use python to recurse a flat file and build a hierarchy使用python递归平面文件并构建层次结构
【发布时间】:2021-04-19 17:41:50
【问题描述】:

我有一个表示层次结构的平面文本文件。它看起来像这样:

0 tom (1)
1   janet (8)
2     harry (1)
3       jules (1)
3       jacob (1)
1   mary (13)
2     jeff (1)
3       sam (2)
1   bob (28)
2     dick (1)

我想读入并构建一个嵌套字典(或某种数据结构)来表示层次结构,以便更容易管理,但我不知道如何迭代和创建数据结构。也许是递归?

第一个数字是层次结构的级别,单词是我要存储的名称,括号中的值是我也要存储的数量。

我想得到类似这样的结果:

{
  "tom": {
    "quantity": 1,
    "names": {
      "janet": {
        "quantity": 8,
        "names": {
          "harry": {
            "quantity": 1,
            "names": {
              "jules": {
                "quantity": 1
              },
              "jacob": {
                "quantity": 1
              }
            }
          }
        }
      },
      "mary": {
        "quantity": 13,
        "names": {
          "jeff": {
            "quantity": 1,
            "names": {
              "sam": {
                "quantity": 2
              }
            }
          }
        }
      },
      "bob": {
        "quantity": 28,
        "names": {
          "dick": {
            "quantity": 1
          }
        }
      }
    }
  }
}

【问题讨论】:

    标签: python dictionary hierarchy


    【解决方案1】:

    你可以使用递归:

    import re
    with open('test_hierarchy.txt') as f:
       d = [[int((k:=re.findall('\d+|\w+', i))[0]), k[1], int(k[-1])] for i in f]
    
    def to_tree(data):
       if not data:
          return {}
       r, _key, _val = {}, None, []
       for a, b, c in data:
          if not a:
             if _key is not None:
                r[_key[0]] = {'quantity':_key[-1], 'names':to_tree(_val)}
             _key, _val = (b, c), []
          else:
             _val.append([a-1, b, c])
       r = {**r, _key[0]:{'quantity':_key[-1], 'names':to_tree(_val)}}
       return {a:{'quantity':b['quantity']} if not b['names'] else b for a, b in r.items()}
    

    import json
    print(json.dumps(to_tree(d), indent=4))
    

    输出:

    {
      "tom": {
         "quantity": 1,
         "names": {
            "janet": {
                "quantity": 8,
                "names": {
                    "harry": {
                        "quantity": 1,
                        "names": {
                            "jules": {
                                "quantity": 1
                            },
                            "jacob": {
                                "quantity": 1
                            }
                        }
                    }
                }
            },
            "mary": {
                "quantity": 13,
                "names": {
                    "jeff": {
                        "quantity": 1,
                        "names": {
                            "sam": {
                                "quantity": 2
                            }
                        }
                    }
                }
            },
            "bob": {
                "quantity": 28,
                "names": {
                    "dick": {
                        "quantity": 1
                    }
                 }
              }
          }
       }
    }
    

    【讨论】: