代码之家  ›  专栏  ›  技术社区  ›  AutoTester213

使用For循环-Python创建动态嵌套Json

  •  0
  • AutoTester213  · 技术社区  · 7 年前

    BuildingGroup
      Building1
       Ward
        Room
         Bed
       Ward
       Ward
         Room
           Bed
           Bed
    

    BuildingGroup始终是根节点,但子节点可能会有所不同。我需要使用参数动态添加子节点。这就是我目前所拥有的。

    import collections
    def add_element(root, path, data):
        if len(path) == 1:
            root[path[0]] = data
        else:
            add_element(root[path[0]], path[1:], data)
    
    
    def create_tree(Wards,WardName,Rooms):
        count = 1
        ward_list=[]    
        room_list= []
        tree = lambda: collections.defaultdict(tree)
        root = tree()
        path_list= ['BuildingGroup', 'Building1']
        for i in range(1,Wards):
            Ward = 'Ward' + str(count)
            path_list,append(Ward)
            ward_list.append(Ward)
            print (ward_list)
            print (path_list)
            count += 1
            add_element(root,path_list, 1 )
        path_list.append(WardName)
        for i in range(1, Rooms):
            Room = 'Room' + str(count)
            path_list.append(Room)
    
            room_list.append(Room)
            print (root)
            add_element(root,path_list, 1 )
    
    create_tree(1, 'Ward1', 10)
    

    Create_tree()应创建一个名为 'Ward1' 再加10 Rooms Ward1

    输出。

    {'BuildingGroup': defaultdict(<function create_tree.<locals>.<lambda> at 0x000002054A7AE510>, {'Building1': defaultdict(<function create_tree.<locals>.<lambda> at 0x000002054A7AE510>, {'Ward1': defaultdict(<function create_tree.<locals>.<lambda> at 0x000002054A7AE510>, {'Room1': 1})})})})
    

    第一次迭代有效,但是在第一次迭代之后,我得到了这个错误。

    TypeError: 'int' object does not support item assignment
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Rob Bricheno    7 年前

    我调试了你的代码,有点奇怪,但我解决了。您的代码只适用于一种情况 Ward 目前,我已经编写了自己的版本,向您展示了一种在多个病房中执行此操作的方法。

    我对您的代码进行了注释,以向您展示主要的更改。

    import collections
    def add_element(root, path, data):
        if len(path) == 1:
            root[path[0]] = data
        else:
            add_element(root[path[0]], path[1:], data)
    
    
    def create_tree(Wards,WardName,Rooms):
        count = 1
        ward_list=[]
        room_list= []
        tree = lambda: collections.defaultdict(tree)
        root = tree()
        path_list= ['BuildingGroup', 'Building1']
        for i in range(1,Wards):
            Ward = 'Ward' + str(count)
            # Check your typos, this line had a ',' in it instead of a '.'
            path_list.append(Ward)
            ward_list.append(Ward)
            print (ward_list)
            print (path_list)
            count += 1
            add_element(root,path_list, 1 )
        path_list.append(WardName)
        for i in range(1, Rooms):
            # Initialise room_list with the path_list from the ward
            room_list = path_list.copy()
            # We have a new variable, 'i' for counting rooms, so don't use 'count' here as it never changes
            Room = 'Room' + str(i)
            # path_list.append(Room) - No! Bad! Don't change the path_list, this is the same for each room
            room_list.append(Room)
            # Use the room_list here instead of the path_list
            add_element(root,room_list, 1 )
            print(root)
    
    my_tree = create_tree(1, 'Ward1', 10)
    

    下面是我的版本:

    import json
    
    
    def create_tree(ward_list, number_of_rooms):
        tree = {'BuildingGroup': {'Building1': {}}}
        for ward in ward_list:
            tree['BuildingGroup']['Building1'][ward] = []
            for i in range(1, number_of_rooms + 1):
                tree['BuildingGroup']['Building1'][ward].append("Room" + str(i))
        return tree
    
    
    wards = ['Ward1', 'Ward2']
    my_tree = create_tree(wards, 10)
    tree_json = json.dumps(my_tree)
    print(tree_json)