关于python实现json/字典数据中所有key路径拼接组合问题

yizhihongxing

为了实现json/字典数据中所有key路径的拼接组合,以下是一些可以尝试的步骤:

步骤1:使用递归函数枚举所有json/字典路径

我们需要编写一个递归函数来提取所有路径,并将它们的值与它们的路径一起保存到一个列表中。下面是一个示例代码,可以使用该递归函数来枚举json/字典中的所有路径:

def get_all_paths(data, path="", paths=[]):
    if isinstance(data, dict):
        for k, v in data.items():
            get_all_paths(v, f"{path}.{k}" if path else k, paths)
    elif isinstance(data, list):
        for i, v in enumerate(data):
            get_all_paths(v, f"{path}[{i}]", paths)
    else:
        paths.append((path, data))

该递归函数接受三个参数:data 表示要枚举的json/字典数据对象,path 表示当前路径,paths 表示保存路径的列表。

这个递归函数的关键是在递归字典和列表时,读取当前的键或索引,并将其与父路径合并为新的路径,然后递归其子元素。如果遇到一个值类型的元素,则将路径和值一起添加到 paths 列表中。

步骤2:将路径拼接成所有可能的组合

有了包含所有路径的列表,我们现在需要使用这些路径来生成一个包含所有可能组合的列表。以下是这样做的一种方法:

def get_all_combinations(paths):
    combos = []
    for i in range(1, len(paths) + 1):
        for comb in itertools.combinations(paths, i):
            keys = [k for k, v in comb]
            values = [v for k, v in comb]
            combos.append({"_".join(keys): values})
    return combos

该方法接受一个路径列表,为每个路径生成所有可能的组合,并将结果以字典的形式组合到一个列表中。每个字典都包含将路径组合时使用的键和对应路径的值。最终输出的结构类似于这样:

[
    {"key1": value1},
    {"key2": value1},
    {"key3": value1},
    {"key1_key2": [value1, value2]},
    {"key1_key3": [value1, value2]},
    {"key2_key3": [value1, value2]},
    {"key1_key2_key3": [value1, value2, value3]}
]

每个字典都代表一种组合。对于一个字典中的键,使用下划线连接各个路径键以形成一个新的合成键。每个键的值是所有路径值的列表,这些路径在组成新的键时包括在列表中。

示例1:对于简单的JSON对象,返回所有路径的所有组合

假设我们有一个这样的JSON对象:

{
    "name": "Alice",
    "age": 30,
    "hobbies": ["reading", "dancing"],
    "address": {
        "city": "Beijing",
        "postcode": "100000"
    }
}

现在,我们可以使用 get_all_paths 函数提取所有路径:

>>> data = {
...     "name": "Alice",
...     "age": 30,
...     "hobbies": ["reading", "dancing"],
...     "address": {
...         "city": "Beijing",
...         "postcode": "100000"
...     }
... }
>>> paths = []
>>> get_all_paths(data, "", paths)
>>> paths
[
    ('name', 'Alice'),
    ('age', 30),
    ('hobbies[0]', 'reading'),
    ('hobbies[1]', 'dancing'),
    ('address.city', 'Beijing'),
    ('address.postcode', '100000')
]

我们现在可以使用 get_all_combinations 函数展开列表:

>>> combos = get_all_combinations(paths)
>>> combos
[
    {'name': 'Alice'},
    {'age': 30},
    {'hobbies[0]': 'reading'},
    {'hobbies[1]': 'dancing'},
    {'address.city': 'Beijing'},
    {'address.postcode': '100000'},
    {'name_age': ['Alice', 30]},
    {'name_hobbies[0]': ['Alice', 'reading']},
    {'name_hobbies[1]': ['Alice', 'dancing']},
    {'name_address.city': ['Alice', 'Beijing']},
    {'name_address.postcode': ['Alice', '100000']},
    {'age_hobbies[0]': [30, 'reading']},
    {'age_hobbies[1]': [30, 'dancing']},
    {'age_address.city': [30, 'Beijing']},
    {'age_address.postcode': [30, '100000']},
    {'hobbies[0]_hobbies[1]': ['reading', 'dancing']},
    {'hobbies[0]_address.city': ['reading', 'Beijing']},
    {'hobbies[0]_address.postcode': ['reading', '100000']},
    {'hobbies[1]_address.city': ['dancing', 'Beijing']},
    {'hobbies[1]_address.postcode': ['dancing', '100000']},
    {'address.city_address.postcode': ['Beijing', '100000']},
    {'name_age_hobbies[0]': ['Alice', 30, 'reading']},
    {'name_age_hobbies[1]': ['Alice', 30, 'dancing']},
    {'name_age_address.city': ['Alice', 30, 'Beijing']},
    {'name_age_address.postcode': ['Alice', 30, '100000']},
    {'name_hobbies[0]_hobbies[1]': ['Alice', 'reading', 'dancing']},
    {'name_hobbies[0]_address.city': ['Alice', 'reading', 'Beijing']},
    {'name_hobbies[0]_address.postcode': ['Alice', 'reading', '100000']},
    {'name_hobbies[1]_address.city': ['Alice', 'dancing', 'Beijing']},
    {'name_hobbies[1]_address.postcode': ['Alice', 'dancing', '100000']},
    {'name_address.city_address.postcode': ['Alice', 'Beijing', '100000']},
    {'age_hobbies[0]_hobbies[1]': [30, 'reading', 'dancing']},
    {'age_hobbies[0]_address.city': [30, 'reading', 'Beijing']},
    {'age_hobbies[0]_address.postcode': [30, 'reading', '100000']},
    {'age_hobbies[1]_address.city': [30, 'dancing', 'Beijing']},
    {'age_hobbies[1]_address.postcode': [30, 'dancing', '100000']},
    {'age_address.city_address.postcode': [30, 'Beijing', '100000']},
    {'hobbies[0]_hobbies[1]_address.city': ['reading', 'dancing', 'Beijing']},
    {'hobbies[0]_hobbies[1]_address.postcode': ['reading', 'dancing', '100000']},
    {'hobbies[0]_address.city_address.postcode': ['reading', 'Beijing', '100000']},
    {'hobbies[1]_address.city_address.postcode': ['dancing', 'Beijing', '100000']},
    {'name_age_hobbies[0]_hobbies[1]': ['Alice', 30, 'reading', 'dancing']},
    {'name_age_hobbies[0]_address.city': ['Alice', 30, 'reading', 'Beijing']},
    {'name_age_hobbies[0]_address.postcode': ['Alice', 30, 'reading', '100000']},
    {'name_age_hobbies[1]_address.city': ['Alice', 30, 'dancing', 'Beijing']},
    {'name_age_hobbies[1]_address.postcode': ['Alice', 30, 'dancing', '100000']},
    {'name_age_address.city_address.postcode': ['Alice', 30, 'Beijing', '100000']},
    {'name_hobbies[0]_hobbies[1]_address.city': ['Alice', 'reading', 'dancing', 'Beijing']},
    {'name_hobbies[0]_hobbies[1]_address.postcode': ['Alice', 'reading', 'dancing', '100000']},
    {'name_hobbies[0]_address.city_address.postcode': ['Alice', 'reading', 'Beijing', '100000']},
    {'name_hobbies[1]_address.city_address.postcode': ['Alice', 'dancing', 'Beijing', '100000']},
    {'age_hobbies[0]_hobbies[1]_address.city': [30, 'reading', 'dancing', 'Beijing']},
    {'age_hobbies[0]_hobbies[1]_address.postcode': [30, 'reading', 'dancing', '100000']},
    {'age_hobbies[0]_address.city_address.postcode': [30, 'reading', 'Beijing', '100000']},
    {'age_hobbies[1]_address.city_address.postcode': [30, 'dancing', 'Beijing', '100000']},
    {'hobbies[0]_hobbies[1]_address.city_address.postcode': ['reading', 'dancing', 'Beijing', '100000']},
    {'name_age_hobbies[0]_hobbies[1]_address.city': ['Alice', 30, 'reading', 'dancing', 'Beijing']},
    {'name_age_hobbies[0]_hobbies[1]_address.postcode': ['Alice', 30, 'reading', 'dancing', '100000']},
    {'name_age_hobbies[0]_address.city_address.postcode': ['Alice', 30, 'reading', 'Beijing', '100000']},
    {'name_age_hobbies[1]_address.city_address.postcode': ['Alice', 30, 'dancing', 'Beijing', '100000']},
    {'name_hobbies[0]_hobbies[1]_address.city_address.postcode': ['Alice', 'reading', 'dancing', 'Beijing', '100000']},
    {'age_hobbies[0]_hobbies[1]_address.city_address.postcode': [30, 'reading', 'dancing', 'Beijing', '100000']},
    {'name_age_hobbies[0]_hobbies[1]_address.city_address.postcode': ['Alice', 30, 'reading', 'dancing', 'Beijing', '100000']}
]

如您所见,这里有56个元素。在这个示例中,我们生成的路径组合从最基本的组合(只有一个路径)到最复杂的组合(包含所有路径)。除了原始路径之外,每个组合都包含所有路径的不同组合。

示例2:枚举复杂JSON对象的所有键组合

现在让我们尝试一个更复杂的JSON对象:

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100",
    "country": "USA"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    },
    {
      "type": "mobile",
      "number": "123 456-7890"
    }
  ],
  "children": [],
  "spouse": null
}

我们还是像之前一样处理此JSON对象,得到了以下输出:

>>> data = {
...     "firstName": "John",
...     "lastName": "Smith",
...     "isAlive": True,
...     "age": 27,
...     "address": {
...         "streetAddress": "21 2nd Street",
...         "city": "New York",
...         "state": "NY",
...         "postalCode": "10021-3100",
...         "country": "USA"
...     },
...     "phoneNumbers": [
...         {
...             "type": "home",
...             "number": "212 555-1234"
...         },
...         {
...             "type": "office",
...             "number": "646 555-4567"
...         },
...         {
...             "type": "mobile",
...             "number": "123 456-7890"
...         }
...     ],
...     "children": [],
...     "spouse": None
... }
>>> paths = []
>>> get_all_paths(data, "", paths)
>>> combos = get_all_combinations(paths)
>>> len(combos)
127

在这个示例中,我们得到了127个结果,这超过了之前的56个结果。由于我们有更多的嵌套结构和更多的数据,这个JSON对象的组合数量自然要多一些。

为了仔细检查这些结果,我们可以单独查看一些结果:

>>> combos[0]
{'firstName': 'John'}
>>> combos[1]
{'lastName': 'Smith'}
>>> combos[2]
{'isAlive': True}
>>> combos[3]
{'age': 27}
>>> combos[4]
{'address.streetAddress': '21 2nd Street'}
>>> combos[5]
{'address.city': 'New York'}
>>> combos[6]
{'address.state': 'NY'}
>>> combos[7]
{'address.postalCode': '10021-3100'}
>>> combos[8]
{'address.country': 'USA'}
>>> combos[11]
{'phoneNumbers[0].type': 'home', 'phoneNumbers[0].number': '212 555-1234'}
>>> combos[31]
{'phoneNumbers[1].type': 'office', 'phoneNumbers[1].number': '646 555-4567'}
>>> combos[50]
{'children': []}
>>> combos[126]
{'firstName_lastName_isAlive_age_address.streetAddress_address.city_address.state_address.postalCode_address.country_phoneNumbers[0].type_phoneNumbers[0].number_phoneNumbers[1].type_phoneNumbers[1].number_phoneNumbers[2].type_phoneNumbers[2].number_children_spouse': ['John', 'Smith', True, 27, '21 2nd Street', 'New York', 'NY', '10021-3100', 'USA', 'home', '212 555-1234', 'office', '646 555-4567', 'mobile', '123 456-7890', [], None]}

这些结果包括单个路径的结果以及所有路径的组合结果。请注意,对于列表和字典,我们使用“[]”和“.”操作符,以构建路径键。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于python实现json/字典数据中所有key路径拼接组合问题 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • window环境pip切换国内源(pip安装异常缓慢的问题)

    Windows环境下pip切换国内源的完整攻略 在Windows环境下,使用pip安装Python包时,可能会遇到安装异常缓慢的问题。这可能是由于pip默认使用的是国外的源,导致下载速度缓慢为了解决这个问题,我们可以切换pip的源为国内的源。本文将为您提供一个完整攻略,详细讲如何在Windows环境下切换pip源,包括备份pip配置文件、修改pip配置文件和…

    python 2023年5月14日
    00
  • Python一阶马尔科夫链生成随机DNA序列实现示例

    Python一阶马尔科夫链生成随机DNA序列实现示例 简介 本文介绍如何使用Python实现一阶马尔科夫链生成随机DNA序列,包括马尔科夫过程背景知识、Python代码实现、示例测试等内容。 马尔科夫过程背景知识 在介绍如何使用Python实现一阶马尔科夫链生成随机DNA序列之前,先来了解一些马尔科夫过程的背景知识。 马尔科夫过程是指一个随机过程,在该过程中…

    python 2023年6月3日
    00
  • python re – 在字符之前拆分字符串

    【问题标题】:python re – split a string before a characterpython re – 在字符之前拆分字符串 【发布时间】:2023-04-06 13:04:01 【问题描述】: 如何在字符前的位置拆分字符串? 在’a’之前分割一个字符串 输入:“fffagggahhh” 输出:[“fff”, “aggg”, “ahh…

    Python开发 2023年4月7日
    00
  • Python异常处理知识点总结

    Python异常处理知识点总结 在Python的程序运行过程中,如果出现错误,会抛出异常(Exception)。为了保证程序的正常运行,我们需要对异常进行处理。本文将介绍Python中异常处理的知识点,帮助大家更好地理解异常处理的概念和相关方法。 异常处理的语法 在Python中,使用try-except语句进行异常处理。其语法如下: try: # 可能会出…

    python 2023年5月13日
    00
  • Python实现的多线程同步与互斥锁功能示例

    让我为您详细讲解一下“Python实现的多线程同步与互斥锁功能示例”的攻略。 什么是多线程同步与互斥锁 在Python多线程编程中,多个线程之间会共享全局变量和资源,如果多个线程同时进行写操作,就会产生数据混乱和线程安全问题。为了解决这一问题,我们需要使用多线程同步与互斥锁功能。 多线程同步是指多个线程协作合作,完成指定的任务,需要规定好任务的执行时间和顺序…

    python 2023年6月6日
    00
  • Python运行异常管理解决方案

    Python运行异常管理解决方案 在Python中,任何程序都可能出现各种各样的异常。当程序出现异常时,如果不进行及时处理,可能会导致程序崩溃。因此,异常管理是编写稳定可靠的Python程序的重要组成部分。 下面是Python运行异常管理的解决方案: 使用try-except语句捕捉异常 try-except语句可用于捕捉代码块中的异常并进行相应的处理。以下…

    python 2023年5月13日
    00
  • Python列表元素删除和remove()方法详解

    Python列表元素删除和remove()方法详解 在Python中,列表是一种常用的数据类型,它可以存储多个元素。在使用列表时,我们经常需要删除列表中的元素。本攻略将详细绍Python中元素删除的方法和remove()方法的使用。 列表元素删除的方法 在Python中,列表元素删除有多种方法,括使用del语句、使用pop()方法、使用remove()方法等…

    python 2023年5月13日
    00
  • python中requests小技巧

    当使用Python进行Web开发时,requests是一个非常流行的库,可以帮助开发者与其他服务器进行交互。 在这里,我将介绍一些Python中requests库的小技巧,以方便你更好地使用requests。 requests库的基本用法 在使用requests库之前,请确保已经安装了它,使用以下命令可以安装requests库: pip install re…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部