2017-09-04 60 views
1

我想从使用python 3的字典中的父键列出所有键。我该如何实现此目标?使用python检索具有预先修改的父键的字典键

这是迄今为止我使用递归函数(以便我可以使用任何深度的字典)。

在这里,如果我不使用header_prefix,我得到没有父键的所有密钥。但是,当我使用header_prefix时,它不断将父键添加到键上。基本上,我不能在适当的位置重置header_prefix

from pprint import pprint 
#%% 

data = { 
    "AWSTemplateFormatVersion": "2010-09-09" , 
    "Description": "Stack for MyProject 01", 
    "Resources": { 
    "elb01": { 
     "Type": "AWS::ElasticLoadBalancing::LoadBalancer", 
     "Properties": { 
     "CrossZone" : "false", 
     "HealthCheck" : { 
      "Target" : "TCP:80", 
      "Interval" : "20" 
     }, 
     "ConnectionSettings": { 
      "IdleTimeout": "120" 
     } 
     } 
    }, 
    "lc01": { 
     "Type": "AWS::AutoScaling::LaunchConfiguration" , 
     "Properties": { 
     "ImageId" : "ami-01010105" , 
     "InstanceType" : "t2.medium" 
     } 
    }, 
    "asg01": { 
     "Type" : "AWS::AutoScaling::AutoScalingGroup", 
     "Properties" : { 
     "HealthCheckGracePeriod" : 300, 
     "HealthCheckType" : "EC2" 
     } 
    } 
    } 
} 
pprint(data) 

#%% 

def get_headers(json_data, headers, header_prefix): 

for key, value in json_data.items(): 
    if type(value) == dict: 
     header_prefix = header_prefix + key + '.' 
     get_headers(value,headers,header_prefix) 
    else: 
     headers.append(header_prefix+key) 

return(headers) 
#%% 
header_list = [] 
prefix = '' 
data_headers = get_headers(data, header_list, prefix) 

pprint(data_headers) 

我从上面的代码,我得到以下的输出:

['AWSTemplateFormatVersion', 
'Description', 
'Resources.elb01.Type', 
'Resources.elb01.Properties.CrossZone', 
'Resources.elb01.Properties.HealthCheck.Target', 
'Resources.elb01.Properties.HealthCheck.Interval', 
'Resources.elb01.Properties.HealthCheck.ConnectionSettings.IdleTimeout', 
'Resources.elb01.lc01.Type', 
'Resources.elb01.lc01.Properties.ImageId', 
'Resources.elb01.lc01.Properties.InstanceType', 
'Resources.elb01.lc01.asg01.Type', 
'Resources.elb01.lc01.asg01.Properties.HealthCheckGracePeriod', 
'Resources.elb01.lc01.asg01.Properties.HealthCheckType'] 

我的预期成果是象下面这样:

['AWSTemplateFormatVersion', 
'Description', 
'Resources.elb01.Type', 
'Resources.elb01.Properties.CrossZone', 
'Resources.elb01.Properties.HealthCheck.Target', 
'Resources.elb01.Properties.HealthCheck.Interval', 
'Resources.elb01.Properties.ConnectionSettings.IdleTimeout', 
'Resources.lc01.Type', 
'Resources.lc01.Properties.ImageId', 
'Resources.lc01.Properties.InstanceType', 
'Resources.asg01.Type', 
'Resources.asg01.Properties.HealthCheckGracePeriod', 
'Resources.asg01.Properties.HealthCheckType'] 

回答

2

这似乎是一个范围界定问题。当您修改header_prefix if语句里面,它会修改它的功能范围,因此对于循环的所有迭代,从而导致不正确的版本被传递到循环

的后面的迭代get_headers简而言之:

变化

header_prefix = header_prefix + key + '.' 
get_headers(value,headers,header_prefix) 

pfx = header_prefix + key + '.' 
get_headers(value,headers,pfx) 

这样一个新的局部变量将被创建并通过拉特而不是在函数范围内更新header_prefix。

(这是不使用get_headers函数中会做

+0

作品的任何变量名。太好了!谢谢你。用我的困惑局部变量以外'header_prefix'是,如何将更新进行更新。我现在看到每当'get_headers'被局部变量('pfx')调用,'header_prefix'被更新。 – Rafiq

+0

很高兴帮助。 从技术上说,每次你调用这个函数时,它会创建一个新的栈帧和一个新的'header_prefix'变量是用任何传入函数的值创建的 –