在 Python 中展平字典或列表的通用 JSON 列表

2023-12-01

我有一组任意 JSON 数据,已在 Python 中解析为字典列表和不同深度的列表。我需要能够将其“扁平化”为一个字典列表。下面的例子:

源数据示例1

[{u'industry': [
   {u'id': u'112', u'name': u'A'},
   {u'id': u'132', u'name': u'B'},
   {u'id': u'110', u'name': u'C'},
   ],
  u'name': u'materials'},
 {u'industry': {u'id': u'210', u'name': u'A'},
  u'name': u'conglomerates'}
]

期望结果示例 1

[{u'name':u'materials', u'industry_id':u'112', u'industry_name':u'A'},
 {u'name':u'materials', u'industry_id':u'132', u'industry_name':u'B'},
 {u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C'},
 {u'name':u'conglomerates', u'industry_id':u'210', u'industry_name':u'A'},
]

对于这个简单的例子来说,这很容易,但我并不总是有这种精确的字典列表结构,还有一层额外的字典列表。在某些情况下,我可能需要遵循相同的方法进行额外的嵌套。因此,我认为我需要递归,但我似乎无法让它发挥作用。

提议的方法

1) 对于每个字典列表,在每个键前面添加一个提供父键名称的“路径”。在上面的示例中,“industry”是包含字典列表的键,因此列表中的每个子字典都添加了“industry”。

2) 将“父”项目添加到列表中的每个字典 - 在本例中,“名称”和“行业”是顶级字典列表中的项目,因此“名称”键/值被添加到每个字典中“工业”中的项目。

我可以想象在某些情况下,您在“父”项中有多个字典列表,甚至是字典的字典,并且将这些子树中的每一个应用到子字典列表中是行不通的。因此,我假设“父”项始终是简单的键/值对。

再举一个例子来说明需要处理的数据结构的潜在变化。

源数据示例2

[{u'industry': [
   {u'id': u'112', u'name': u'A'},
   {u'id': u'132', u'name': u'B'},
   {u'id': u'110', u'name': u'C', u'company': [
                            {u'id':'500', u'symbol':'X'},
                            {u'id':'502', u'symbol':'Y'},
                            {u'id':'504', u'symbol':'Z'},
                  ]
   },
   ],
  u'name': u'materials'},
 {u'industry': {u'id': u'210', u'name': u'A'},
  u'name': u'conglomerates'}
]

期望结果示例 2

[{u'name':u'materials', u'industry_id':u'112', u'industry_name':u'A'},
 {u'name':u'materials', u'industry_id':u'132', u'industry_name':u'B'},
 {u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C', 
                        u'company_id':'500', u'company_symbol':'X'},
 {u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C', 
                        u'company_id':'502', u'company_symbol':'Y'},
 {u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C', 
                        u'company_id':'504', u'company_symbol':'Z'},
 {u'name':u'conglomerates', u'industry_id':u'210', u'industry_name':u'A'},
]

我已经查看了其他几个示例,但似乎找不到适用于这些示例的示例。

有什么建议或指示吗?我花了一些时间尝试构建一个递归函数来处理这个问题,但几个小时后没有运气......

因一次失败的尝试而更新

def _flatten(sub_tree, flattened=[], path="", parent_dict={}, child_dict={}):
    if type(sub_tree) is list:
        for i in sub_tree:
            flattened.append(_flatten(i,
                                      flattened=flattened,
                                      path=path,
                                      parent_dict=parent_dict,
                                      child_dict=child_dict
                                      )
                            )
        return flattened
    elif type(sub_tree) is dict:
        lists = {}
        new_parent_dict = {}
        new_child_dict = {}
        for key, value in sub_tree.items():
            new_path = path + '_' + key
            if type(value) is dict:
                for key2, value2 in value.items():
                    new_path2 = new_path + '_' + key2
                    new_parent_dict[new_path2] = value2
            elif type(value) is unicode:
                new_parent_dict[key] = value
            elif type(value) is list:
                lists[new_path] = value
        new_parent_dict.update(parent_dict)
        for key, value in lists.items():
            for i in value:
                flattened.append(_flatten(i,
                                      flattened=flattened,
                                      path=key,
                                      parent_dict=new_parent_dict,
                                      )
            )
        return flattened

我得到的结果是“无”对象的 231x231 矩阵 - 显然我遇到了递归失控的麻烦。

我尝试了一些额外的“从头开始”尝试,但都以类似的失败模式失败。


好吧。我的解决方案有两个功能。首先,splitObj,负责将对象拆分为平面数据和子列表或子对象,稍后需要递归。第二,flatten,实际上迭代对象列表,进行递归调用并负责为每次迭代重建最终对象。

def splitObj (obj, prefix = None):
    '''
    Split the object, returning a 3-tuple with the flat object, optionally
    followed by the key for the subobjects and a list of those subobjects.
    '''
    # copy the object, optionally add the prefix before each key
    new = obj.copy() if prefix is None else { '{}_{}'.format(prefix, k): v for k, v in obj.items() }

    # try to find the key holding the subobject or a list of subobjects
    for k, v in new.items():
        # list of subobjects
        if isinstance(v, list):
            del new[k]
            return new, k, v
        # or just one subobject
        elif isinstance(v, dict):
            del new[k]
            return new, k, [v]
    return new, None, None

def flatten (data, prefix = None):
    '''
    Flatten the data, optionally with each key prefixed.
    '''
    # iterate all items
    for item in data:
        # split the object
        flat, key, subs = splitObj(item, prefix)

        # just return fully flat objects
        if key is None:
            yield flat
            continue

        # otherwise recursively flatten the subobjects
        for sub in flatten(subs, key):
            sub.update(flat)
            yield sub

请注意,这并不能完全产生您想要的输出。其原因是您的输出实际上不一致。在第二个示例中,对于行业中嵌套有公司的情况,嵌套在输出中不可见。因此,我的输出将生成industry_company_id and industry_company_symbol:

>>> ex1 = [{u'industry': [{u'id': u'112', u'name': u'A'},
                          {u'id': u'132', u'name': u'B'},
                          {u'id': u'110', u'name': u'C'}],
            u'name': u'materials'},
           {u'industry': {u'id': u'210', u'name': u'A'}, u'name': u'conglomerates'}]
>>> ex2 = [{u'industry': [{u'id': u'112', u'name': u'A'},
                          {u'id': u'132', u'name': u'B'},
                          {u'company': [{u'id': '500', u'symbol': 'X'},
                                        {u'id': '502', u'symbol': 'Y'},
                                        {u'id': '504', u'symbol': 'Z'}],
                           u'id': u'110',
                           u'name': u'C'}],
            u'name': u'materials'},
           {u'industry': {u'id': u'210', u'name': u'A'}, u'name': u'conglomerates'}]

>>> pprint(list(flatten(ex1)))
[{'industry_id': u'112', 'industry_name': u'A', u'name': u'materials'},
 {'industry_id': u'132', 'industry_name': u'B', u'name': u'materials'},
 {'industry_id': u'110', 'industry_name': u'C', u'name': u'materials'},
 {'industry_id': u'210', 'industry_name': u'A', u'name': u'conglomerates'}]
>>> pprint(list(flatten(ex2)))
[{'industry_id': u'112', 'industry_name': u'A', u'name': u'materials'},
 {'industry_id': u'132', 'industry_name': u'B', u'name': u'materials'},
 {'industry_company_id': '500',
  'industry_company_symbol': 'X',
  'industry_id': u'110',
  'industry_name': u'C',
  u'name': u'materials'},
 {'industry_company_id': '502',
  'industry_company_symbol': 'Y',
  'industry_id': u'110',
  'industry_name': u'C',
  u'name': u'materials'},
 {'industry_company_id': '504',
  'industry_company_symbol': 'Z',
  'industry_id': u'110',
  'industry_name': u'C',
  u'name': u'materials'},
 {'industry_id': u'210', 'industry_name': u'A', u'name': u'conglomerates'}]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 中展平字典或列表的通用 JSON 列表 的相关文章

  • 跟踪 pypi 依赖项 - 谁在使用我的包

    无论如何 是否可以通过 pip 或 PyPi 来识别哪些项目 在 Pypi 上发布 可能正在使用我的包 也在 PyPi 上发布 我想确定每个包的用户群以及可能尝试积极与他们互动 预先感谢您的任何答案 即使我想做的事情是不可能的 这实际上是不
  • 为什么 json.Unmarshal 返回映射而不是预期的结构?

    看看这个游乐场 http play golang org p dWku6SPqj5 http play golang org p dWku6SPqj5 基本上 我正在工作的图书馆收到了interface 作为参数 然后需要json Unma
  • 来自 iPhone/iPad 的 json Web 服务

    有人可以帮助我解决如何从 iphone 或 ipad 使用 json Web 服务的问题吗 这里我的要求是使用 API 密钥实现 json webservice 如果可能的话发布一些教程或示例链接 谢谢 规范的 JSON 处理库是here
  • YOLOv8获取预测边界框

    我想将 OpenCV 与 YOLOv8 集成ultralytics 所以我想从模型预测中获取边界框坐标 我该怎么做呢 from ultralytics import YOLO import cv2 model YOLO yolov8n pt
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • 如何将张量流模型部署到azure ml工作台

    我在用Azure ML Workbench执行二元分类 到目前为止 一切正常 我有很好的准确性 我想将模型部署为用于推理的 Web 服务 我真的不知道从哪里开始 azure 提供了这个doc https learn microsoft co
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • 在Python中检索PostgreSQL数据库的新记录

    在数据库表中 第二列和第三列有数字 将会不断添加新行 每次 每当数据库表中添加新行时 python 都需要不断检查它们 当 sql 表中收到的新行数低于 105 时 python 应打印一条通知消息 警告 数量已降至 105 以下 另一方面
  • Docker 中的 Python 日志记录

    我正在 Ubuntu Web 服务器上的 Docker 容器中测试运行 python 脚本 我正在尝试查找由 Python Logger 模块生成的日志文件 下面是我的Python脚本 import time import logging
  • 在 Sphinx 文档中*仅*显示文档字符串?

    Sphinx有一个功能叫做automethod从方法的文档字符串中提取文档并将其嵌入到文档中 但它不仅嵌入了文档字符串 还嵌入了方法签名 名称 参数 我如何嵌入only文档字符串 不包括方法签名 ref http www sphinx do
  • 如何通过索引列表从 dask 数据框中选择数据?

    我想根据索引列表从 dask 数据框中选择行 我怎样才能做到这一点 Example 假设我有以下 dask 数据框 dict A 1 2 3 4 5 6 7 B 2 3 4 5 6 7 8 index x1 a2 x3 c4 x5 y6 x
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • import matplotlib.pyplot 给出 AttributeError: 'NoneType' 对象没有属性 'is_interactive'

    我尝试在 Pycharm 控制台中导入 matplotlib pyplt import matplotlib pyplot as plt 然后作为回报我得到 Traceback most recent call last File D Pr
  • 根据列 value_counts 过滤数据框(pandas)

    我是第一次尝试熊猫 我有一个包含两列的数据框 user id and string 每个 user id 可能有多个字符串 因此会多次出现在数据帧中 我想从中导出另一个数据框 一个只有那些user ids列出至少有 2 个或更多string
  • 将 Python 中的日期与日期时间进行比较

    所以我有一个日期列表 datetime date 2013 7 9 datetime date 2013 7 12 datetime date 2013 7 15 datetime date 2013 7 18 datetime date
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • 使用随机放置的 NaN 创建示例 numpy 数组

    出于测试目的 我想创建一个M by Nnumpy 数组与c随机放置的 NaN import numpy as np M 10 N 5 c 15 A np random randn M N A mask np nan 我在创建时遇到问题mas

随机推荐

  • 带空括号的默认构造函数

    是否有任何充分的理由表明一组空的圆括号 圆括号 对于调用 C 中的默认构造函数无效 MyObject object ok default ctor MyObject object blah ok MyObject object error
  • 使用 Actionscript 更改字符串中的字符

    的相反词是什么String charAt 如果我有一个字符串 var Str String Hello World 如何更改第五个字符 例如从 更改为 我可以像这样获取第五个字符 var C String Str charAt 5 但如何设
  • xCode:未找到库 - lPods-Bolts - 退出代码 1

    您好 我遇到这个问题 ld 找不到 lPods Bolts 的库 clang 错误 链接器命令失败 退出代码为 1 使用 v 查看 调用 不过 我从 Facebook 文档下载了 Bolt 包并将其放入我的支持文件中 另外 我使用的是Coc
  • 新 C# 8.0 开关表达式的运算符优先级是什么?

    我刚刚将当前项目升级到新发布的 NET Standard 2 1 和 C 8 0 并决定转换一些大型项目switch语句变成新的 更加紧凑的表达式语法 由于返回的值进一步用于某些计算 我想知道新的值如何switch当输入变量位于运算符旁边时
  • 将文件批量上传到特定联系人 Salesforce

    我需要向 salesforce 中的特定用户上传大约 2000 个文档 我有一个 csv 文件 其中包含 Salesforce 分配的 ContactID 以及桌面上文件的直接路径 每个联系人的特定文件 URL 已包含在 csv 中 我怎样
  • 需要突出显示 jquery datepicker 中的日期范围[重复]

    这个问题在这里已经有答案了 我正在使用 jQuery UI 显示内联日期选择器 其中我有一个开始日期和一个结束日期 我想强调一下它们之间的日期 您可以使用 jQuery UI 日期选择器演出日之前函数并在其中检查是否必须根据您的范围突出显示
  • 在Python中读取字段中包含逗号的CSV文件

    我需要读取一个 CSV 文件 其中包含带有逗号的字段 因此我对包含逗号的字段进行了双引号 例如 1 text1 text2 text3 text4 a b c 但是当我尝试在 Python 中读取文件时 我得到用逗号分隔的字段 如下所示 r
  • Jssor Slider:响应式代码

    我正在使用 Jssor 滑块 http www jssor com demos slider cluster html 由于我的幻灯片很大 宽度约为 2000 像素 因此它们在较小的设备 甚至 iPad 上会显着缩放 我不介意在较小的设备上
  • 获取扩展文件属性

    我找到了这个帖子 这解释了如何获取 net 中的扩展文件属性 但它指向一篇已有 10 年历史的代码项目文章 该线程本身已有 5 年历史 现在是否有更好的方法来获取扩展文件属性 如标题 副标题 剧集名称等 我真正想做的是获取各个文件的扩展文件
  • Socket.IO 中的套接字参考

    我是 Nodejs 新手 正在尝试使用 socket io 我正在尝试将消息发送到特定的套接字 因此我想我将存储对套接字的引用 var controls var clients var control io of control on co
  • Twitter Typeahead.js Bloodhound 远程返回未定义

    远程版本 Twitter Typeahead js 无法正常工作 我的建议得到 未定义 任何帮助 将不胜感激 代码如下 JS var films new Bloodhound datumTokenizer Bloodhound tokeni
  • 使用 Apache Camel UnZippedMessageProcessor 解压缩文件

    尝试使用 Apache Camel 解压缩文件 我尝试了中给出的示例http camel apache org zip file dataformat html但我找不到解压消息处理器班级 这是代码 import java util Ite
  • 如何在 Sublime Text 中自定义文件类型与语法关联?

    我希望 Sublime 2 编辑器将 sbt 文件 以突出显示语法 视为 Scala 语言 与 scala 相同 但我找不到在哪里进行设置 你碰巧知道吗 在 Sublime Text 中 在 v2 x 和 v3 x 中均得到确认 有一个菜单
  • SSRS动态共享数据源

    我有一个 ASP Net 网站 它使用 Microsoft Report Viewer Control 显示各种 SSRS 报告 我需要能够在运行时指定数据源 似乎我应该能够在呈现报告时指定 共享 数据源的名称 但我确实找不到方法来做到这一
  • 从 PostgreSQL 中的时间戳中提取日期 (yyyy/mm/dd)

    我想从 PostgreSQL 中的时间戳中提取日期部分 我需要它是一个 postgresqlDATE类型 以便我可以将其插入到另一个需要的表中DATE value 例如 如果我有2011 05 26 09 00 00 我想2011 05 2
  • 带有令牌参数的 https URL:安全性如何?

    在我们的网站上 我们根据用户的私人信息 通过表格提供 向用户提供模拟 我们希望允许他们稍后返回模拟结果 但不强迫他们创建登录 密码帐户 我们考虑过向他们发送一封带有链接的电子邮件 他们可以从中获取结果 但是 自然地 我们必须保护这个 URL
  • 将 XML 文件读入 DataTable 的代码

    我编写了以下代码 用于读取给定的 xml 文件并将内容写入数据表 请不要建议使用 LinqToXml 因为该选项已被规则 因为这是一个遗留应用程序 create the DataTable that will hold the data D
  • 在 python for 循环中使用“or”来定义默认序列

    我在某处看到过 for 循环的用法 def func seq None for i in seq or 1 2 3 print i func 3 4 5 Will print 3 4 5 func Will print 1 2 3 似乎当使
  • 六位unicode转义值比较

    例如 我有一个六位数的 unicode 字符U 100000我想与另一个进行比较char在我的 C 代码中 我读到的MSDN 文档是这个字符不能用 a 来表示char 并且必须由string 字符文字中不允许使用 U 10000 到 U 1
  • 在 Python 中展平字典或列表的通用 JSON 列表

    我有一组任意 JSON 数据 已在 Python 中解析为字典列表和不同深度的列表 我需要能够将其 扁平化 为一个字典列表 下面的例子 源数据示例1 u industry u id u 112 u name u A u id u 132 u