【问题标题】:Create Parent Dictionary by key [closed]按键创建父字典[关闭]
【发布时间】:2013-09-04 23:36:18
【问题描述】:

我这里有一个这样的字典:

example_dict = { 
    'key1' : 'value1',
    'key2' : 'value2',
    'key3' : 
    { 
        'key3a': 'value3a' 
    },
    'key4' : 
    { 
        'key4a': 
        { 
            'key4aa': 'value4aa',
            'key4ab': 'value4ab',
            'key4ac': 
            {
                'key4ac1': [0,1,2],
                'key4ac2': (3,4,5),
                'key4ac3': [
                    {
                        'sub_key_x': 0,
                        'sub_key_y': 1,
                    }, 
                    6
                ]               
            }
        },
        'key4b': 'value4b'
    }
}

我尝试使用此问题的递归代码创建父字典: Get parents keys from nested dictionary

问题在于元组或列表,它们打破了循环。 我想在字典中搜索字符串,使用 difflib 对最匹配的结果进行排序。

如果有人知道如何在字典中搜索键/值来创建父字典,那将非常高兴。

例如:

search_in_dict(example_dict, 'sub key')
# returning the content of:
# example_dict['key4']['key4a']['key4ac']['key4ac3']

亲切的问候 BaumKuchen

【问题讨论】:

    标签: python dictionary parent-child


    【解决方案1】:

    我不知道你为什么要这样做,当数据结构大小增加时,这种事情会变得很慢。有一个平面字典可能会更好,但是必须定义平面化算法。

    我已经为我认为你想要的做了一些粗略的事情。 flatten 方法返回类似于items ((键,值)元组的列表),其中“键”实际上是键的元组。这是必要的,因为字典可能包含相同的键,因此当转换到平面命名空间(需要唯一键)时,就会出现冲突。

    class recurdict(dict):
        '''
        Recursive Dictionary
        '''
        def __init__(self, idict=None, **kwargs):
            dict.__init__(self)
            if idict is not None:
                self.update(idict)
            if len(kwargs):
                self.update(kwargs)
    
        def __contains__(self, key):
            return (key in self.keys())
    
        def __getitem__(self, key):
            if self.__contains__(key):
                return self.___getitem__(self, key)
            else:
                raise KeyError(key)
    
        @staticmethod
        def ___getitem__(idict, key):
            if dict.__contains__(idict, key):
                return dict.__getitem__(idict, key) 
            else:
                result = None
                for k, v in idict.iteritems():
                    if hasattr(v, "keys"):
                        result = recurdict.___getitem__(v, key)
                        if(result):
                            return result
                        else:
                            continue
    
        def flatten(self):
            return self._flatten(self)
    
        @staticmethod
        def _flatten(idict, key_chain = []):
            found_keys = []
            for k, v in idict.iteritems():
                if hasattr(v, "keys"):
                    found_keys.extend(recurdict._flatten(v, key_chain + [k]))
                else:
                    found_keys.append((tuple(key_chain + [k]), v))
            return found_keys
    
        def has_key(self, key):
            return self.__contains__(key)
    
        def keys(self):
            return self._keys(self)
    
        @staticmethod
        def _keys(idict):
            found_keys = dict.keys(idict)
            for k, v in idict.iteritems():
                if hasattr(v, "keys"):
                    found_keys.extend(recurdict._keys(v))
            return found_keys
    
        def update(self, other=None, **kwargs):
            if other is None:
                pass
            elif hasattr(other, "iteritems"):
                for k, v in other.iteritems():
                    self.__setitem__(k,v)
            elif hasattr(other, "keys"):
                for k in other.keys():
                    self.__setitem__(k,other.__getitem__(k))
            else:
                for k, v in other:
                    self.__setitem__(k,v)
            if kwargs:
                self.update(kwargs)
    
    example_dict = recurdict\
    ({ 
        "key1" : "value1",
        "key2" : "value2",
        "key3" : 
        { 
            "key3a": "value3a" 
        },
        "key4" : 
        { 
            "key4a": 
            { 
                "key4aa": "value4aa",
                "key4ab": "value4ab",
                "key4ac": 
                {
                    "key4ac1": [0,1,2],
                    "key4ac2": (3,4,5),
                    "key4ac3":
                    [
                        {
                            "sub_key_x": 0,
                            "sub_key_y": 1,
                        }, 
                        6
                    ]               
                }
            },
            "key4b": "value4b"
        }
    })
    
    print example_dict.keys()
    print "key1" in example_dict
    print "key4ac1" in example_dict
    print example_dict["key4ac1"]
    for (k, v) in example_dict.flatten():
        print (k, v)
    

    【讨论】:

    • 非常感谢,效果很好 =) 要回答我为什么要这样做的问题,我正在编写一个脚本来操作字典(用户选择一个键并显示内容,.. ),到目前为止有效,但我还想实现一个搜索功能来更快地找到一些键/值。
    猜你喜欢
    • 2019-01-05
    • 2015-03-07
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 2022-01-25
    相关资源
    最近更新 更多