如何根据子值的存在删除字典中的值

How to delete values in a dict based on the presence of child values

我有一个看起来像这样的字典:

OrderedDict([('arguments', {'index': 1, 'parent': None}), ('controls', {'index': 2, 'parent': None}), ('examples', {'index': 3, 'parent': None}), ('journal', {'index': 4, 'parent': None}), ('journal/config', {'index': 5, 'parent': 'journal'}), ('journal/journaltest', {'index': 6, 'parent': 'journal'}), ('procs', {'index': 7, 'parent': None}), ('processor', {'index': 8, 'parent': None}), ('prediction', {'index': 9, 'parent': None}), ('reports', {'index': 10, 'parent': None}), ('tooki', {'index': 11, 'parent': None}), ('tooki/help', {'index': 12, 'parent': 'tooki'}), ('tooki/lime', {'index': 13, 'parent': 'tooki'}), ('tooki/medium', {'index': 14, 'parent': 'tooki'}), ('tooki/share', {'index': 15, 'parent': 'tooki'}), ('tooki/trigger', {'index': 16, 'parent': 'tooki'})])

如何遍历此字典的元素,并排除任何具有“'parent':None”没有子元素的元素(意思是,这个字典中没有其他元素有这个作为父元素)。

预期输出:

OrderedDict([('journal', {'index': 4, 'parent': None}), ('journal/config', {'index': 5, 'parent': 'journal'}), ('journal/journaltest', {'index': 6, 'parent': 'journal'}), ('tooki', {'index': 11, 'parent': None}), ('tooki/help', {'index': 12, 'parent': 'tooki'}), ('tooki/lime', {'index': 13, 'parent': 'tooki'}), ('tooki/medium', {'index': 14, 'parent': 'tooki'}), ('tooki/share', {'index': 15, 'parent': 'tooki'}), ('tooki/trigger', {'index': 16, 'parent': 'tooki'})])

一个非常愚蠢的方法:

x = OrderedDict(blah blah blah)

keys_to_exclude = []
for key1, val1 in x.items():
    if val1['parent'] is None:
        remove = True
        for key2, val2 in x.items():
            if val2['parent'] == key1:
                remove = False  
        if remove:
            keys_to_exclude.append(key1)

for key in keys_to_exclude:
    x.pop(key, None) 

这段代码显然有 O(n^2) 的复杂度。一种更聪明的方法是预先为每个元素添加一个 'child' 键,复杂度为 O(n)。

这是对我有用的东西。最终输出的顺序不一样,但是我按照你说的条件可以满足排除key value对的要求。

a = OrderedDict([('arguments', {'index': 1, 'parent': None}),
                 ('controls', {'index': 2, 'parent': None}),
                 ('examples', {'index': 3, 'parent': None}),
                 ('journal', {'index': 4, 'parent': None}),
                 ('journal/config', {'index': 5, 'parent': 'journal'}),
                 ('journal/journaltest', {'index': 6, 'parent': 'journal'}),
                 ('procs', {'index': 7, 'parent': None}),
                 ('processor', {'index': 8, 'parent': None}),
                 ('prediction', {'index': 9, 'parent': None}),
                 ('reports', {'index': 10, 'parent': None}),
                 ('tooki', {'index': 11, 'parent': None}),
                 ('tooki/help', {'index': 12, 'parent': 'tooki'}),
                 ('tooki/lime', {'index': 13, 'parent': 'tooki'}),
                 ('tooki/medium', {'index': 14, 'parent': 'tooki'}),
                 ('tooki/share', {'index': 15, 'parent': 'tooki'}),
                 ('tooki/trigger', {'index': 16, 'parent': 'tooki'})])
od = OrderedDict()
for each in a:
    if (parent := a[each].get('parent', None)):
        od[parent] = a[parent]

for each in a:
    if (element := a[each].get('parent', None)):
        od[each] = a[each]

print(od)

我没有理解代码的简单性。第一个循环将 parents 保存到新的 OrdereDict。第二个保存了children。如果未满足您的要求,请告诉我。

ins = OrderedDict(...)

parents = set(elem['parent'] for elem in ins.values() if elem['parent'] is not None)

d = OrderedDict()
for key, value in ins.items():
    if value['parent'] is not None:
        d[key] = value
    elif any(ins.get(k) is not None for k in parents):
        d[key] = value

使用一组父键可以消除很多复杂性。在您的情况下,有很多元素,但只会检查两个键。

我觉得这个功能可以帮到你

def orderedDict(data_list: list):
    result: list = []
    for data in data_list:
        is_ok = True
        if data[1]["parent"] is None:
            is_ok = False
            for item in [x[0] for x in [y for y in data_list if y[0] != data[0]]]:
                if data[0]+"/" in item:
                    is_ok = True
                    break
        if is_ok:
            result.append(data)
    return result

使用方法:

if __name__ == '__main__':
    data = ([('arguments', {'index': 1, 'parent': None}), ('controls', {'index': 2, 'parent': None}),
             ('examples', {'index': 3, 'parent': None}), ('journal', {'index': 4, 'parent': None}),
             ('journal/config', {'index': 5, 'parent': 'journal'}),
             ('journal/journaltest', {'index': 6, 'parent': 'journal'}), ('procs', {'index': 7, 'parent': None}),
             ('processor', {'index': 8, 'parent': None}), ('prediction', {'index': 9, 'parent': None}),
             ('reports', {'index': 10, 'parent': None}), ('tooki', {'index': 11, 'parent': None}),
             ('tooki/help', {'index': 12, 'parent': 'tooki'}), ('tooki/lime', {'index': 13, 'parent': 'tooki'}),
             ('tooki/medium', {'index': 14, 'parent': 'tooki'}),
             ('tooki/share', {'index': 15, 'parent': 'tooki'}),
             ('tooki/trigger', {'index': 16, 'parent': 'tooki'})])
    result = orderedDict(data_list=data)
    print(result)