将复杂的字典扁平化,同时使用点作为分隔符压缩键。

huangapple go评论72阅读模式
英文:

flatten a complex dict, while compressing keys using dot as a separator

问题

Sure, here's the translation of the code you provided:

我正在尝试编写一个 Python3 函数当然也可以使用现有的库),将这个输入展平

{
  'key1': 1, 
  'key2dict': {'subkey1': 1, 'subkey2': 2},
  'key3listOfDict': [
    {'subkey3': 3, 'subkey4': 4},
    {'subkey5': 5, 'subkey6': 6}
  ],
  'key4nestedListOfDict': [
    {
      'subkey7': 7, 
      'subkeyNested': [
        {'subkey8': 8}, 
        {'subkey9': 9}
      ]
    }
  ]
}

展平为

[
  {
    'key1': 1, 
    'key2dict.subkey1': 1,
    'key2dict.subkey2': 2,
    'key3listOfDict.subkey3': 3,
    'key3listOfDict.subkey4': 4,
    'key4nestedListOfDict.subkey7': 7,
    'key4nestedListOfDict.subkeyNested.subkey8': 8,
  },
  {
    'key1': 1, 
    'key2dict.subkey1': 1,
    'key2dict.subkey2': 2,
    'key3listOfDict.subkey3': 3,
    'key3listOfDict.subkey4': 4,
    'key4nestedListOfDict.subkey7': 7,
    'key4nestedListOfDict.subkeyNested.subkey9': 9,
  },
  {
    'key1': 1, 
    'key2dict.subkey1': 1,
    'key2dict.subkey2': 2,
    'key3listOfDict.subkey5': 5,
    'key3listOfDict.subkey6': 6,
    'key4nestedListOfDict.subkey7': 7,
    'key4nestedListOfDict.subkeyNested.subkey8': 8,
  },
  {
    'key1': 1, 
    'key2dict.subkey1': 1,
    'key2dict.subkey2': 2,
    'key3listOfDict.subkey5': 5,
    'key3listOfDict.subkey6': 6,
    'key4nestedListOfDict.subkey7': 7,
    'key4nestedListOfDict.subkeyNested.subkey9': 9,
  }
]

我遇到的主要挑战是正确处理对象列表和嵌套对象列表我进行了一些研究并尝试了一些方法但效果不如预期

非常感谢任何帮助

Let me know if you need anything else.

英文:

I'm trying come up with a python3 function (using existing libs also works, of course) that would flatten this input:

{
'key1': 1, 
'key2dict': {'subkey1': 1, 'subkey2': 2},
'key3listOfDict': [
{'subkey3': 3, 'subkey4': 4},
{'subkey5': 5, 'subkey6': 6}
],
'key4nestedListOfDict': [
{
'subkey7': 7, 
'subkeyNested': [
{'subkey8': 8}, 
{'subkey9': 9}
]
}
]
}

into this:

[
{
'key1': 1, 
'key2dict.subkey1': 1,
'key2dict.subkey2': 2,
'key3listOfDict.subkey3': 3,
'key3listOfDict.subkey4': 4,
'key4nestedListOfDict.subkey7': 7,
'key4nestedListOfDict.subkeyNested.subkey8': 8,
},
{
'key1': 1, 
'key2dict.subkey1': 1,
'key2dict.subkey2': 2,
'key3listOfDict.subkey3': 3,
'key3listOfDict.subkey4': 4,
'key4nestedListOfDict.subkey7': 7,
'key4nestedListOfDict.subkeyNested.subkey9': 9,
},
{
'key1': 1, 
'key2dict.subkey1': 1,
'key2dict.subkey2': 2,
'key3listOfDict.subkey5': 5,
'key3listOfDict.subkey6': 6,
'key4nestedListOfDict.subkey7': 7,
'key4nestedListOfDict.subkeyNested.subkey8': 8,
},
{
'key1': 1, 
'key2dict.subkey1': 1,
'key2dict.subkey2': 2,
'key3listOfDict.subkey5': 5,
'key3listOfDict.subkey6': 6,
'key4nestedListOfDict.subkey7': 7,
'key4nestedListOfDict.subkeyNested.subkey9': 9,
}
]

The main challenge I'm having is the proper handling the lists-of-objects, and nested lists-of-objects.
I researched and tried some myself, but those didn't work as expected.

Any help would be much appreciated!

for the record, I have these so far (not doing the work properly..):

from collections.abc import MutableMapping
def flatten(dictionary, parent_key='', separator='.'):
items = []
for key, value in dictionary.items():
new_key = parent_key + separator + key if parent_key else key
if isinstance(value, MutableMapping):
items.extend(flatten(value, new_key, separator=separator).items())
else:
items.append((new_key, value))
return dict(items)
def flatten_handle_lists(row):
rows = []
for i, (key, value) in enumerate(row.items()):
if isinstance(value, list):
for j, v in enumerate(value):
expansion_row = dict(row)
del expansion_row[key]
expansion_row.update(flatten(v, key, '.'))
rows.append(expansion_row)
return rows

答案1

得分: 1

这可以分为两个步骤:首先处理列表,然后进行字典展开。

英文:

It's much simpler to split this into two steps: handle the lists first, then do the dictionary flattening afterward.

import itertools
from collections.abc import Mapping
def explode_nested_lists(dictionary):
"""
Turn a nested dictionary with lists representing different possible subtrees
into a list of dictionaries for each combination of the subtrees.
"""
options = {}
for k, v in dictionary.items():
if isinstance(v, list):
options[k] = list(itertools.chain(*map(explode_nested_lists, v)))
elif isinstance(v, Mapping):
options[k] = explode_nested_lists(v)
else:
options[k] = [v]
keys = list(options.keys())
return [
dict(zip(keys, vals)) for vals in itertools.product(*(options[k] for k in keys))
]
def flatten_keys(dictionary, separator="."):
"""Flatten a nested dictionary by joining keys with a separator."""
result = {}
for key, value in dictionary.items():
if isinstance(value, Mapping):
result.update(
(key + separator + k, v)
for k, v in flatten_keys(value, separator).items()
)
else:
result[key] = value
return result
def flatten(dictionary, separator="."):
return [flatten_keys(d, separator) for d in explode_nested_lists(dictionary)]

huangapple
  • 本文由 发表于 2023年5月18日 04:43:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276065.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定