提问人:shachar0n 提问时间:5/18/2023 最后编辑:shachar0n 更新时间:5/21/2023 访问量:105
展平复杂的字典,同时使用 dot 作为分隔符压缩键
flatten a complex dict, while compressing keys using dot as a separator
问:
我正在尝试想出一个 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,
}
]
我遇到的主要挑战是正确处理对象列表和嵌套对象列表。 我自己研究并尝试了一些,但这些方法没有按预期工作。
任何帮助将不胜感激!
作为记录,到目前为止我有这些(没有正确地完成工作..):
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赞
yut23
5/18/2023
#1
将其分为两个步骤要简单得多:首先处理列表,然后再进行字典扁平化。
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)]
评论
0赞
shachar0n
5/18/2023
是的,我明白你的意思......我被困在尝试先进行扁平化,然后再取消嵌套/分解这些列表。但你的方法听起来更好,看起来很有希望。我现在正在用你的代码执行一些测试,但我认为这就是我一直在寻找的确切答案。谢谢!将很快更新..
评论
]