【问题标题】:Split a list of dictionary of dictionaries into a single dictionary将字典字典列表拆分为单个字典
【发布时间】:2021-09-09 18:20:39
【问题描述】:

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

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

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

{'id': 'xxxxx', 'idMemberCreator': 'xxxxx', 'data': {'reason': 'xxxxx', 'board': {'id': 'xxxxx'}, '组织' : {'id': 'xxxxx', 'name': 'xxxxx'}}, 'type': 'xxxxx', 'date': 'xxxxx', 'appCreator': 'xxxxx', 'limits': {} ,'memberCreator':{'id':'xxxxx','用户名':'xxxxx','activityBlocked':'xxxxx','avatarHash':'xxxxx','avatarUrl':'xxxxx','fullName': 'xxxxx', 'idMemberReferrer': 'xxxxx', '首字母': 'x', 'nonPublic': {}, 'nonPublicAvailable': 'xxxxx'}}

注意字典包含几个字典,例如'数据'

我正在尝试循环遍历它以将其分解为不包含字典的字典,因此它可能如下所示

{'id': 'xxxxx', 'idMemberCreator': 'xxxxx', '数据原因': 'xxxxx', '数据板': {'id': 'xxxxx'}, '数据组织': { 'id':'xxxxx','name':'xxxxx'},'type':'xxxxx','date':'xxxxx','appCreator':'xxxxx','limits':无,... }

由于 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:字典在迭代期间改变了大小

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

谁能指点我正确的方向?

非常感谢:)

【问题讨论】:

    标签: json python-3.x dictionary recursion pyodbc


    【解决方案1】:

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

    如果你将它提供给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'}
    

    【讨论】:

    • 谢谢。这比我预期的要好得多。有了这个,我什至可能不需要使用 SQL,而是可以使用 Jupyter 笔记本
    • 把它变回我用过的字典,dict(zip(list(pd.json_normalize(actions[0]).columns), pd.json_normalize(actions[0]).values[0 ].tolist()))
    猜你喜欢
    • 2010-12-19
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多