英文:
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)]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论