2017-09-04 28 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'變量是用任何傳入函數的值創建的 –