Flatten nested dictionaries, compressing keys

前端 未结 28 2264
遇见更好的自我
遇见更好的自我 2020-11-22 01:16

Suppose you have a dictionary like:

{\'a\': 1,
 \'c\': {\'a\': 2,
       \'b\': {\'x\': 5,
             \'y\' : 10}},
 \'d\': [1, 2, 3]}

Ho

28条回答
  •  死守一世寂寞
    2020-11-22 01:39

    I was thinking of a subclass of UserDict to automagically flat the keys.

    class FlatDict(UserDict):
        def __init__(self, *args, separator='.', **kwargs):
            self.separator = separator
            super().__init__(*args, **kwargs)
    
        def __setitem__(self, key, value):
            if isinstance(value, dict):
                for k1, v1 in FlatDict(value, separator=self.separator).items():
                    super().__setitem__(f"{key}{self.separator}{k1}", v1)
            else:
                super().__setitem__(key, value)
    

    ‌ The advantages it that keys can be added on the fly, or using standard dict instanciation, without surprise:

    >>> fd = FlatDict(
    ...    {
    ...        'person': {
    ...            'sexe': 'male', 
    ...            'name': {
    ...                'first': 'jacques',
    ...                'last': 'dupond'
    ...            }
    ...        }
    ...    }
    ... )
    >>> fd
    {'person.sexe': 'male', 'person.name.first': 'jacques', 'person.name.last': 'dupond'}
    >>> fd['person'] = {'name': {'nickname': 'Bob'}}
    >>> fd
    {'person.sexe': 'male', 'person.name.first': 'jacques', 'person.name.last': 'dupond', 'person.name.nickname': 'Bob'}
    >>> fd['person.name'] = {'civility': 'Dr'}
    >>> fd
    {'person.sexe': 'male', 'person.name.first': 'jacques', 'person.name.last': 'dupond', 'person.name.nickname': 'Bob', 'person.name.civility': 'Dr'}
    

提交回复
热议问题