如何将嵌套字典转换为列表的字符串
How to convert nested dictionary into the string of list
我有这个嵌套的 python 字典
dictionary = {'a':'1', 'b':{'c':'2', 'd':{'z':'5', 'e':{'f':'13', 'g':'14'}}}}
所以推荐的输出将是:
output = ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:13']
使用recursive function
而不使用递归函数
在这种情况下,我总是喜欢先尝试解决容易的部分。
def flatten_dict(dictionary):
output = []
for key, item in dictionary.items():
if isinstance(item, dict):
output.append(f'{key}:???') # Hm, here is the difficult part
else:
output.append(f'{key}:{item}')
return output
尝试 flatten_dict(dictionary)
现在打印 ['a:1', 'b:???']
这显然不够好。一方面,列表中的三个项目太少了。
首先,我想改用生成器函数。这目前比较复杂,但稍后会得到回报。
def flatten_dict(dictionary):
return list(flatten_dict_impl(dictionary))
def flatten_dict_impl(dictionary):
for key, item in dictionary.items():
if isinstance(item, dict):
yield f'{key}:???'
else:
yield f'{key}:{item}'
输出还没有变化。是时候回顾了。
你希望输出是一个平面列表,这意味着我们必须在 item
是字典的情况下产生多个东西。只是,什么东西?让我们尝试在这个子词典中插入对 flatten_dict_impl
的递归调用,这似乎是最直接的方法。
# flatten_dict is unchanged
def flatten_dict_impl(dictionary):
for key, item in dictionary.items():
if isinstance(item, dict):
for value in flatten_dict_impl(item):
yield f'{key}:{value}'
else:
yield f'{key}:{item}'
输出现在是 ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:14']
,这是你想要的输出,除了最后的 14,但我认为这是你的错字。
现在是 non-recursive 路线。为此,我们需要自己管理一些状态,因为我们需要知道我们有多深。
def flatten_dict_nonrecursive(dictionary):
return list(flatten_dict_nonrecursive_impl(dictionary))
def flatten_dict_nonrecursive_impl(dictionary):
dictionaries = [iter(dictionary.items())]
keys = []
while dictionaries:
try:
key, value = next(dictionaries[-1])
except StopIteration:
dictionaries.pop()
if keys:
keys.pop()
else:
if isinstance(value, dict):
keys.append(key)
dictionaries.append(iter(value.items()))
else:
yield ':'.join(keys + [key, value])
现在这给出了正确的输出,但更不容易理解,而且更长。我也花了很长时间才做对。可能有更短和更明显的方法来做到这一点,但我错过了,但通常递归问题更容易用递归函数解决。
这种方法仍然有用:如果您的字典嵌套了数百或数千层,那么尝试递归执行它可能会溢出堆栈。
希望对您有所帮助。让我知道是否需要了解更多细节或其他内容。
您可以使用 NestedDict
。首先安装ndicts
pip install ndicts
然后:
from ndicts.ndicts import NestedDictionary
dictionary = {'a': '1', 'b': {'c' :'2', 'd': {'z': '5', 'e': {'f': '13', 'g': '14'}}}}
nd = NestedDict(dictionary)
output = [":".join((*key, value)) for key, value in nd.items()]
我有这个嵌套的 python 字典
dictionary = {'a':'1', 'b':{'c':'2', 'd':{'z':'5', 'e':{'f':'13', 'g':'14'}}}}
所以推荐的输出将是:
output = ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:13']
使用recursive function
而不使用递归函数
在这种情况下,我总是喜欢先尝试解决容易的部分。
def flatten_dict(dictionary):
output = []
for key, item in dictionary.items():
if isinstance(item, dict):
output.append(f'{key}:???') # Hm, here is the difficult part
else:
output.append(f'{key}:{item}')
return output
尝试 flatten_dict(dictionary)
现在打印 ['a:1', 'b:???']
这显然不够好。一方面,列表中的三个项目太少了。
首先,我想改用生成器函数。这目前比较复杂,但稍后会得到回报。
def flatten_dict(dictionary):
return list(flatten_dict_impl(dictionary))
def flatten_dict_impl(dictionary):
for key, item in dictionary.items():
if isinstance(item, dict):
yield f'{key}:???'
else:
yield f'{key}:{item}'
输出还没有变化。是时候回顾了。
你希望输出是一个平面列表,这意味着我们必须在 item
是字典的情况下产生多个东西。只是,什么东西?让我们尝试在这个子词典中插入对 flatten_dict_impl
的递归调用,这似乎是最直接的方法。
# flatten_dict is unchanged
def flatten_dict_impl(dictionary):
for key, item in dictionary.items():
if isinstance(item, dict):
for value in flatten_dict_impl(item):
yield f'{key}:{value}'
else:
yield f'{key}:{item}'
输出现在是 ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:14']
,这是你想要的输出,除了最后的 14,但我认为这是你的错字。
现在是 non-recursive 路线。为此,我们需要自己管理一些状态,因为我们需要知道我们有多深。
def flatten_dict_nonrecursive(dictionary):
return list(flatten_dict_nonrecursive_impl(dictionary))
def flatten_dict_nonrecursive_impl(dictionary):
dictionaries = [iter(dictionary.items())]
keys = []
while dictionaries:
try:
key, value = next(dictionaries[-1])
except StopIteration:
dictionaries.pop()
if keys:
keys.pop()
else:
if isinstance(value, dict):
keys.append(key)
dictionaries.append(iter(value.items()))
else:
yield ':'.join(keys + [key, value])
现在这给出了正确的输出,但更不容易理解,而且更长。我也花了很长时间才做对。可能有更短和更明显的方法来做到这一点,但我错过了,但通常递归问题更容易用递归函数解决。
这种方法仍然有用:如果您的字典嵌套了数百或数千层,那么尝试递归执行它可能会溢出堆栈。
希望对您有所帮助。让我知道是否需要了解更多细节或其他内容。
您可以使用 NestedDict
。首先安装ndicts
pip install ndicts
然后:
from ndicts.ndicts import NestedDictionary
dictionary = {'a': '1', 'b': {'c' :'2', 'd': {'z': '5', 'e': {'f': '13', 'g': '14'}}}}
nd = NestedDict(dictionary)
output = [":".join((*key, value)) for key, value in nd.items()]