【问题标题】:Retrieving dictionary keys with pre-fixed parent keys using python使用python检索具有预先固定的父键的字典键
【发布时间】:2018-02-12 12:10:56
【问题描述】:

我正在尝试使用 python 3 从字典中列出所有带有父键的键。我怎样才能实现这个目标?

到目前为止,我使用了一个递归函数(这样我就可以将它与任何深度的字典一起使用)。

这里,如果我不使用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']

【问题讨论】:

    标签: json python-3.x csv dictionary key


    【解决方案1】:

    这似乎是一个范围界定问题。当您在 if 语句中修改 header_prefix 时,它会在函数范围内修改它,因此对于循环的所有迭代,都会导致在循环的后续迭代中将不正确的版本传递给 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 函数中未使用的任何变量名都可以

    【讨论】:

    • 有效。伟大的!谢谢。我对使用header_prefix 以外的局部变量的困惑是它的更新方式是如何更新的。我现在可以看到,每当使用局部变量 (pfx) 调用 get_headers 时,header_prefix 都会更新。
    • 很高兴它有帮助。从技术上讲,每次调用该函数时,它都会创建一个新的堆栈框架,并使用传递给函数的任何值创建一个新的 header_prefix 变量
    猜你喜欢
    • 2015-12-22
    • 1970-01-01
    • 2015-06-16
    • 2017-10-09
    • 2014-08-14
    • 2021-10-20
    • 2021-11-25
    • 2014-05-29
    • 2016-01-28
    相关资源
    最近更新 更多