python - python中任意长度的嵌套字典的组合

标签 python combinations python-itertools cartesian-product

我正在寻找一个函数,它将采用嵌套字典,并生成值的组合/乘积。

我的查询与此处指定的问题类似,但我似乎无法调整答案来满足我的需求: Cartesian product of nested dictionaries of lists

我希望有这样的输入:

d = {
  "country": [1, 2],
  "health_state": [
    {"healthy": [1]},
    {"breast cancer": {"stage": [1, 2]}}
  ]
}

产生如下输出:

[
{{"country":1},{"health state":{"healthy":1}}},
{{"country":2},{"health state":{"healthy":1}}},
{{"country":1},{"health state":{"breast cancer":{"stage":1}}}},
{{"country":1},{"health state":{"breast cancer":{"stage":2}}}},
{{"country":2},{"health state":{"breast cancer":{"stage":1}}}},
{{"country":2},{"health state":{"breast cancer":{"stage":2}}}}
]

在此示例中,输出是一个人可以占据的“状态”列表

  • 列表(输入)的任何两个元素不应位于返回列表(输出)的同一元素中,例如某人不能同时在国家 1 和国家 2
  • 字典(输入)中的所有键应在列表(输出)的同一元素中返回,例如有人在国家 1 并且也处于 health_state。如果该健康状况是“乳腺癌”,那么他们也处于第一阶段或第二阶段

我可以设想一个需要大量 for 循环的解决方案,检查元素是否是字典、列表或两者都不是,但这似乎效率低下,尤其是对于深层嵌套的字典。我怀疑有一个更优雅的解决方案,使用 itertools.product 和递归?

最佳答案

您可以将递归与itertools.product结合使用:

import itertools as it
d = {'country': [1, 2], 'health_state': [{'healthy': [1]}, {'breast cancer': {'stage': [1, 2]}}]}
def c_prod(d):
  if isinstance(d, list):
     for i in d:
        yield from ([i] if not isinstance(i, (dict, list)) else c_prod(i))
  else:
     for i in it.product(*map(c_prod, d.values())):
        yield dict(zip(d.keys(), i))

print(list(c_prod(d)))

输出:

[{'country': 1, 'health_state': {'healthy': 1}}, 
 {'country': 1, 'health_state': {'breast cancer': {'stage': 1}}}, 
 {'country': 1, 'health_state': {'breast cancer': {'stage': 2}}}, 
 {'country': 2, 'health_state': {'healthy': 1}}, 
 {'country': 2, 'health_state': {'breast cancer': {'stage': 1}}}, 
 {'country': 2, 'health_state': {'breast cancer': {'stage': 2}}}]

上面代码的输出生成一个字典列表,但您所需的输出镜像了一个字典列表列表 (list[list[dict]]),因此,最终的转换可以是制作:

r = [[{j:k} for j, k in i.items()] for i in c_prod(d)]

输出:

[[{'country': 1}, {'health_state': {'healthy': 1}}], [{'country': 1}, {'health_state': {'breast cancer': {'stage': 1}}}], [{'country': 1}, {'health_state': {'breast cancer': {'stage': 2}}}], [{'country': 2}, {'health_state': {'healthy': 1}}], [{'country': 2}, {'health_state': {'breast cancer': {'stage': 1}}}], [{'country': 2}, {'health_state': {'breast cancer': {'stage': 2}}}]]

关于python - python中任意长度的嵌套字典的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70178819/

相关文章:

Python itertools 多处理

python 长度为 k 的 0,1 的所有可能组合

python - 如何在pygame中获得可变的键盘输入?

python - 从 aws-lambda 导入 pysftp 时如何修复导入错误 "No module named ' _cffi_backend' "

python - 对句子上的所有 k 执行 K 组合的算法

algorithm - 如何在 Perl 中生成长度为 k 的所有有序组合?

python - 可逆笛卡尔积元素/索引转换功能

python - 有没有办法将新列添加到 Pandas 数据框,将新列的每个唯一值附加到数据框的每个现有行?

python - 为什么我的pygame sndarray对象有这种失真?

r - 找出一组数字的所有组合,这些数字加起来等于某个总数