删除保存值的python dict中的一个级别

时间:2016-01-14 19:26:56

标签: python json python-2.7 python-3.x dictionary

我有以下python字典:

'load_balancers': {'App': {'DJMatcher': {'security_group': 'sg-618d1c05', 'service_name': 'djmatcher/svc', 'certificateId': 'net', 'health_check_path': '/djmatcherstatus/ma.html', 'DNS': {'fde': {'record_name': 'platform-enrichment-djmatcher', 'ttl': 60}}}}}

现在它基本上代表以下YAML:

 LoadBalancers:
    App:
        DJMatcher:
            certificateId: 'net'
            health_check_path: /djmatcherstatus/ma.html
            security_group: *svc_sg1
            service_name: *sn
            DNS:
                fde:
                    record_name: platform-enrichment-djmatcher
                    ttl: 60

我想删除第二级密钥 - “App”并保持其余部分,这意味着生成的python字典应该成为我删除密钥App的地方,但现在该值变为其父密钥的值“load_balancers”:

'load_balancers': {'DJMatcher': {'security_group': 'sg-618d1c05', 'service_name': 'djmatcher/svc', 'certificateId': 'net', 'health_check_path': '/djmatcherstatus/ma.html', 'DNS': {'fde': {'record_name': 'platform-enrichment-djmatcher', 'ttl': 60}}}}

实现这一目标的任何好方法?

5 个答案:

答案 0 :(得分:6)

derp['load_balancers'] = derp['load_balancers']['App']

答案 1 :(得分:4)

虽然问题没有要求一般的解决方案,但我认为为了未来的搜索者的利益可能值得努力(如果OP在未来遇到更复杂的情况)。

def removeLevel(d, level):
    if type(d) != type({}):
        return d

    if level == 0:
        removed = {}
        for k, v in d.iteritems():
            if type(v) != type({}):
                continue
            for kk, vv in v.iteritems():
                removed[kk] = vv
        return removed

    removed = {}
    for k, v in d.iteritems():
        removed[k] = removeLevel(v, level-1)
    return removed

以递归方式运行,直到达到要删除的正确级别,然后复制所有子键。

例如:

>>> d = {'load_balancers': {'App': {'DJMatcher': {'security_group': 'sg-618d1c05', 'service_name': 'djmatcher/svc', 'certificateId': 'net', 'health_check_path': '/djmatcherstatus/ma.html', 'DNS': {'fde': {'record_name': 'platform-enrichment-djmatcher', 'ttl': 60}}}}}}
>>> removeLevel(d, 1)

{'load_balancers': {'DJMatcher': {'security_group': 'sg-618d1c05', 'service_name': 'djmatcher/svc', 'certificateId': 'net', 'DNS': {'fde': {'record_name': 'platform-enrichment-djmatcher', 'ttl': 60}}, 'health_check_path': '/djmatcherstatus/ma.html'}}}

>>> d2 = {'a': {'b':1, 'e':{'f':4}}, 'c':{'d':2}}
>>> removeLevel(d2, 1)

{'a': {'f': 4}, 'c': {}}

>>> removeLevel(d2, 0)

{'b': 1, 'e': {'f': 4}, 'd': 2}

答案 2 :(得分:2)

thedict['load_balancers'] = thedict['load_balancers'].pop('App')

答案 3 :(得分:0)

dt[dt.keys()[0]] = dt[dt.keys()[0]].values()[0]

答案 4 :(得分:0)

尝试解决类似问题时,我发现了这个问题。上面的人提供了一种递归方法,但是它使用Python 2语法,并且仅允许基于“级别”数字删除键,这不符合我的目的。这是一个使用更现代语法的示例,该示例允许指定要删除的键:

def remove_levels(in_dict, keys_to_remove):
    try:
        result = {}
        for key, value in in_dict.items():
            if key in keys_to_remove:
                result = {**result, **remove_levels(value, keys_to_remove)}
            else:
                result[key] = remove_levels(value, keys_to_remove)
        return result
    except AttributeError:
        return in_dict

您将以如下方式使用它:

loadbalancers = {
    'LoadBalancers': {
        'DJMatcher': {
            'certificateId': 'net',
            'health_check_path': '/djmatcherstatus/ma.html',
            'security_group': '*svc_sg1',
            'service_name': '*sn',
            'DNS': {
                'fde': {
                     'record_name': 'platform-enrichment-djmatcher',
                     'ttl': 60
                }
            }
        }
    }
}
remove_levels(loadbalancers, {"App"})

输出:

{'LoadBalancers': {'DJMatcher': {'certificateId': 'net',
   'health_check_path': '/djmatcherstatus/ma.html',
   'security_group': '*svc_sg1',
   'service_name': '*sn',
   'DNS': {'fde': {'record_name': 'platform-enrichment-djmatcher',
     'ttl': 60}}}}}