如何将嵌套的python字典转换为简单的命名空间?

2024-09-27 04:24:22 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个深度为N的嵌套字典。如何将每个内部嵌套字典转换为一个简单的命名空间

example_input = {key0a: "test", key0b: {key1a: {key2a: {...keyNx}, key2b: "test"} ,key1b: "test"}}

example_output = SimpleNamespace(key0a: "test", key0b: SimpleNamespace(key1a: SimpleNamespace(key2a: SimpleNamespace(...keyNx), key2b: "test"), key1b: "test"))

如果给出了示例输入dict,是否有更好的替代方法使字典的键可以按点表示法访问(例如示例输入.key0a),而无需外部依赖关系


Tags: test示例input字典example空间命名simplenamespace
3条回答

仅回答您的第二个(最后一个)问题-这是一个热门话题,有许多不同的项目(非标准)使您的字典成为点符号对象

例如这个-attrdict。通过pip install attrdict安装它

用法示例:

Try it online!

from attrdict import AttrDict
d = {'a': 1, 'b': [{'c': 2}, {'d': {'e': {'f': {5: {'g': 3}}}}}]}
ad = AttrDict(d)
print(ad.b[1].d.e.f(5).g) # 3

使用递归

example_input = {'key0a': "test", 'key0b': 
                 {'key1a': {'key2a': 'end', 'key2b': "test"} ,'key1b': "test"}, 
                 "something": "else"}
def parse(d):
  x = SimpleNamespace()
  _ = [setattr(x, k, parse(v)) if isinstance(v, dict) else setattr(x, k, v) for k, v in d.items() ]    
  return x

result = parse(example_input)
print (result)

输出:

namespace(key0a='test', 
          key0b=namespace(key1a=namespace(key2a='end', key2b='test'), key1b='test'), 
          something='else')

基于mujjija的解决方案,这就是我想到的。完整代码如下

from types import SimpleNamespace


def parse(data):
    if type(data) is list:
        return list(map(parse, data))
    elif type(data) is dict:
        sns = SimpleNamespace()
        for key, value in data.items():
            setattr(sns, key, parse(value))
        return sns
    else:
        return data


info = {
    'country': 'Australia',
    'number': 1,
    'slangs': [
        'no worries mate',
        'winner winner chicken dinner',
        {
            'no_slangs': [123, {'definately_not': 'hello'}]
        }
    ],
    'tradie': {
        'name': 'Rizza',
        'occupation': 'sparkie'
    }
}

d = parse(info)
assert d.country == 'Australia'
assert d.number == 1
assert d.slangs[0] == 'no worries mate'
assert d.slangs[1] == 'winner winner chicken dinner'
assert d.slangs[2].no_slangs[0] == 123
assert d.slangs[2].no_slangs[1].definately_not == 'hello'
assert d.tradie.name == 'Rizza'
assert d.tradie.occupation == 'sparkie'

如果我没有弄错的话,Python不支持尾部调用优化。因此,在Python中使用深层递归函数时请小心。对于小的例子,它应该是好的

更新

另一个版本object_hook有筑巢的魔力。我更喜欢这个版本,因为我可以直接将它们提供给jinja2模板引擎

import json


class _DotDict(dict):
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__


def dot(data=None):
    if data is []:
        return []
    return json.loads(json.dumps(data), object_hook=_DotDict) if data else _DotDict()

相关问题 更多 >

    热门问题