python字符串到json转换

时间:2017-09-04 06:08:36

标签: python json python-2.7

我在下面有一个python脚本,它会加载一个yaml文件。参数作为列表传入,因此我可以遍历它们以向字典添加值。下面的代码添加了参数,但json没有正确格式化,如当前和所需的json结果中所示。任何正确方向的帮助表示赞赏。感谢。

YAML档案

  policies:
  - name: ec2age
    resource: ec2
    filters:      
      - State.Name: running
      - "tag:ResourceCreatedBy": present
      - and:
        - type: instance-age
          days: 30
          op: ge

Python脚本:

#!/usr/bin/python
import sys
import argparse
import json
import yaml

parser = argparse.ArgumentParser()
parser.add_argument("-y", "--yaml_file", type=str)
parser.add_argument("-b", "--business_unit", type=str)
parser.add_argument("-p", "--platform", type=str)
parser.add_argument("-c", "--client", type=str)
args = parser.parse_args()

with open(args.yaml_file, 'r') as stream:
    data = yaml.load(stream)

inner_dict = [args.business_unit, args.platform, args.client]

for item in list(inner_dict):
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform

print json.dumps(data)

当前结果:

{
"policies": [
    {
    "resource": "ec2",
    "name": "ec2age",
    "filters": [
        {
        "tag:BUSINESS_UNIT": "TEST_FLITE",
        "State.Name": "running"
        },
        {
        "tag:ResourceCreatedBy": "present"
        },
        {
        "and": [
            {
            "type": "instance-age",
            "days": 30,
            "op": "ge"
            }
        ]
        }
    ]
    }
]
}

期望的结果:

{
"policies": [
    {
    "resource": "ec2",
    "name": "ec2age",
    "filters": [
        {
        "tag:BUSINESS_UNIT": "TEST_FLITE"
        },
        {
        "tag:PLATFORM": "Android"
        },
        {            
        "State.Name": "running"
        },
        {
        "tag:ResourceCreatedBy": "present"
        },
        {
        "and": [
            {
            "type": "instance-age",
            "days": 30,
            "op": "ge"
            }
        ]
        }
    ]
    }
]
}

2 个答案:

答案 0 :(得分:1)

这部分代码:

inner_dict = [args.business_unit, args.platform, args.client]

for item in list(inner_dict):
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform

并没有多大意义。首先,inner_dict已经是一个列表。我们没有理由再次将其转换为列表 - list(inner_dict)

其次,在循环中,您迭代3次,对列表中的每个项目迭代一次,并在每个迭代步骤中重复相同的语句。您不会在这些陈述中使用item

从这里,不知道YAML文件的结构,很难提供解决方案,但你应该寻找上面提到的行。我试着没有循环,只执行:

data['policies'][0]['filters'].append({'tag:BUSINESS_UNIT': args.business_unit})
data['policies'][0]['filters'].append({'tag:PLATFORM': args.platform})

编辑:添加YAML文件内容后,我可以为您提供进一步的解释。 致电data['policies'][0]['filters']时,请致电此部分:

[
    {            
        "State.Name": "running"
    },
    {
        "tag:ResourceCreatedBy": "present"
    },
    {
        "and": [
            {
                "type": "instance-age",
                "days": 30,
                "op": "ge"
            }
        ]
    }
]

因此data['policies'][0]['filters'][0]会返回:

{            
    "State.Name": "running"
}

data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit会为该字典添加新的key:value对:

{            
    "State.Name": "running",
    "tag:BUSINESS_UNIT": "TEST_FLITE"
}

循环没有帮助,它在每个迭代步骤中都是一样的。

我的提议会将所需的键:值对作为字典附加到列表的末尾。如果订单真的很重要,那么你必须改变清单。看看模块collections.deque

答案 1 :(得分:1)

在您的代码中,

inner_dict = [args.business_unit, args.platform, args.client]

for item in list(inner_dict):
    """
      following line appends adds key to 0'th dict which is 
     {
    "tag:BUSINESS_UNIT": "TEST_FLITE",
    "State.Name": "running"
    }
    """
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform

你可以这样做,

#!/usr/bin/python

from __future__ import print_function
import sys
import argparse
import json
import yaml

parser = argparse.ArgumentParser()
parser.add_argument("-y", "--yaml_file", type=str)
parser.add_argument("-b", "--business_unit", type=str)
parser.add_argument("-p", "--platform", type=str)
parser.add_argument("-c", "--client", type=str)
args = parser.parse_args()

with open(args.yaml_file, 'r') as stream:
    data = yaml.load(stream)


inner_list = [{"tag:BUSINESS_UNIT" : args.business_unit},
              {"tag:PLATFORM" : args.platform},
              # {"tag:CLIENT" : args.client} #if needed
             ]

for i, item in enumerate(inner_list):
    data['policies'][0]['filters'].insert(i, item)

print(json.dumps(data))