将字典列表拆分为单个字典

Split a list of dictionary of dictionaries into a single dictionary

我正在尝试从 Trello 看板的操作中获取 JSON 并将其放入 MS SQL 数据库中。 我的代码查看我的用户帐户有权访问的每个板。 每个板都有一个动作列表 字典中的每个动作 但是一些字典值本身就是字典。即嵌套字典

我最终得到了一个长度可变的字典列表,其中还可以包含不同长度的嵌套字典 我正在尝试将每个操作/每个字典简化为一个字典,这样我就可以将键用作 header 列 SQL table,这样我就可以将值插入到 SQL(使用 pyodbc)作为单个字典。尝试使用带有嵌套字典的字典插入 pyodbc 会产生键错误。如果所有的值都是字符串等就没有问题

单个操作的示例可能采用以下格式。字典中的键各不相同,所以如果某件事没有发生,它就不会出现在字典中,因此字典的长度和键数会有所不同 - 所以我不能对所有键进行硬编码

{'id': 'xxxxx', 'idMemberCreator': 'xxxxx', 'data': {'reason': 'xxxxx', 'board': {'id': 'xxxxx'}, 'organization': {'id': 'xxxxx', 'name': 'xxxxx'} }, 'type': 'xxxxx', 'date': 'xxxxx', 'appCreator': 'xxxxx', 'limits': {}, 'memberCreator': {'id': 'xxxxx', 'username': 'xxxxx', 'activityBlocked': 'xxxxx', 'avatarHash': 'xxxxx', 'avatarUrl': 'xxxxx', 'fullName': 'xxxxx', 'idMemberReferrer': 'xxxxx', 'initials': 'x', 'nonPublic':{},'nonPublicAvailable':'xxxxx'}}

注意字典包含多个字典,例如'data'

我正在尝试遍历它以将其分解成一个不包含字典的字典,因此它可能看起来像下面这样

{'id': 'xxxxx', 'idMemberCreator': 'xxxxx', 'data reason': 'xxxxx', 'data board': {'id': 'xxxxx'}, 'data organization': {'id': 'xxxxx', 'name': 'xxxxx'}, 'type': 'xxxxx', 'date': 'xxxxx', 'appCreator': 'xxxxx', 'limits': None, ...}

因为 python 无法分辨列表中的数据类型(仅当值在列表中时)我想创建一个如下所示的检查函数

 def checkfordict(action):
     for k,v in action.items():
         if type(v) is dict:
             return True

并在循环的一部分中使用它来删除多次迭代中的嵌套字典

>>> for action in actions:
...     while checkfordict(action):
...         for k,v in action.items():
...             if type(v) is dict:
...                 for k2,v2 in v.items():
...                     temp[k+k2] = v2
...             else:
...                 temp[k] = v
...         temp
...         action = temp

但这会导致错误 追溯(最近一次通话): 文件“”,第 4 行,位于 RuntimeError:字典在迭代期间改变了大小

我希望它递归工作,直到所有嵌套字典都被修改,我不认为使用复制函数会起作用,因为它只会迭代一次并且不会继续迭代,直到所有嵌套字典都消失.

谁能给我指出正确的方向?

非常感谢:)

您不应修改正在迭代的对象。

如果你把它喂给 pandas.json_normalize(...) 你可以看到它被压扁了。

>>> pd.json_normalize(b, sep="_").columns
Index(['id', 'idMemberCreator', 'type', 'date', 'appCreator', 'data_reason',
       'data_board_id', 'data_organization_id', 'data_organization_name',
       'memberCreator_id', 'memberCreator_username',
       'memberCreator_activityBlocked', 'memberCreator_avatarHash',
       'memberCreator_avatarUrl', 'memberCreator_fullName',
       'memberCreator_idMemberReferrer', 'memberCreator_initials',
       'memberCreator_nonPublicAvailable'],
      dtype='object')

也快速搜索指向https://www.geeksforgeeks.org/flattening-json-objects-in-python/

# Function for flattening 
# json
def flatten_json(y):
    out = {}
  
    def flatten(x, name =''):
          
        # If the Nested key-value 
        # pair is of dict type
        if type(x) is dict:
              
            for a in x:
                flatten(x[a], name + a + '_')
                  
        # If the Nested key-value
        # pair is of list type
        elif type(x) is list:
              
            i = 0
              
            for a in x:                
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x
  
    flatten(y)
    return out

给出

>>> flatten_json(b)
{'id': 'xxxxx', 'idMemberCreator': 'xxxxx', 'data_reason': 'xxxxx', 'data_board_id': 'xxxxx', 'data_organization_id': 'xxxxx', 'data_organization_name': 'xxxxx', 'type': 'xxxxx', 'date': 'xxxxx', 'appCreator': 'xxxxx', 'memberCreator_id': 'xxxxx', 'memberCreator_username': 'xxxxx', 'memberCreator_activityBlocked': 'xxxxx', 'memberCreator_avatarHash': 'xxxxx', 'memberCreator_avatarUrl': 'xxxxx', 'memberCreator_fullName': 'xxxxx', 'memberCreator_idMemberReferrer': 'xxxxx', 'memberCreator_initials': 'x', 'memberCreator_nonPublicAvailable': 'xxxxx'}