繁体   English   中英

无法使用python从Json文件中获取特定值

[英]Not able to get specific value from Json file using python

我很难从json文件中获取一些数据。 我能够获得一些数据,但是当我想进一步挖掘细节时,我会出错并且没有卡住。

运行下面的脚本返回错误

AttributeError: 'list' object has no attribute 'get'

我知道它的列表,但是我不确定如何获取其余的对象列表。

脚本

ifile=open('source.json', 'r')
ofile=open('extract.json', 'w')
json_decode=json.load(ifile)
myresult=[]
for item in json_decode:
    mydict={}
    mydict['sID']=item.get('Ls id')
    my_dict['dID']=item.get('items').get('Link ID').get('Metric').get('Link Type')
    mydict['type']=item.get('Type')
    myresult.append(mydict)
myjson=json.dumps(myresult, ofile)
ofile.write(myjson)
ofile.close()

源Json文件

[
  {
    "Ls age": "201",
    "items": [
      {
        "Link ID": "1.1.1.2",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.4",
        "Link Type": "P-2-P",
        "Metric": "1",
        "Data": "192.168.100.34"
      },
      {
        "Link ID": "192.168.100.33",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.1",
        "Link Type": "P-2-P",
        "Metric": "1",
        "Data": "192.168.100.53"
      }
    ],
    "Len": "84",
    "Ls id": "1.1.1.2",
    "Adv rtr": "1.1.1.2",
    "Type": "Router",
    "Link count": "5"
  },
  {
    "Ls age": "1699",
    "seq#": "80008d72",
    "items": [
      {
        "Link ID": "1.1.1.1",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.1",
        "Link Type": "StubNet",
        "Metric": "12",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.3",
        "Link Type": "P-2-P",
        "Metric": "10",
        "Data": "192.168.100.26"
      },
      {
        "Link ID": "192.168.100.25",
        "Link Type": "StubNet",
        "Metric": "10",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.2",
        "Link Type": "P-2-P",
        "Metric": "10",
        "Data": "192.168.100.54"
      },
      {
        "Link ID": "192.168.100.53",
        "Link Type": "StubNet",
        "Metric": "10",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      }
    ],
    "Len": "96",
    "Ls id": "1.1.1.1",
    "chksum": "0x16fc",
    "Adv rtr": "1.1.1.1",
    "Type": "Router",
    "Options": "ASBR  E",
    "Link count": "6"
  }
]

预期结果如下

[
  {
    "type": "Router",
    "sID": "1.1.1.2",
    "dID": "1.1.1.2",
    "LinkType":"StubNet",
    "Metric":"1"
  },
  { 
    "type": "Router",
    "sID": "1.1.1.2", 
    "dID": "1.1.1.4",
    "Link Type": "P-2-P",
    "Metric": "1"
  },
  {
    "type": "Router",
    "sID": "1.1.1.2",
    "dID": "192.168.100.33",
    "LinkType":"StubNet",
    "Metric":"1"   
  },   
  { 
    "type": "Router",     
    "sID": "1.1.1.2",     
    "dID":"1.1.1.1",
    "Link Type": "P-2-P",
    "Metric": "1"
  },
  {
    "type": "Router",
    "sID": "1.1.1.1",
    "dID": "1.1.1.1",     
    "LinkType":"StubNet",     
    "Metric":"1"  
   },   
   {     
    "type": "Router",
    "sID": "1.1.1.1",
    "dID":"1.1.1.1",
    "Link Type": "StubNet",
    "Metric": "12"
  },
  {
    "type": "Router",
    "sID": "1.1.1.1",
    "dID": "1.1.1.3",
    "LinkType":"P-2-P",
    "Metric":"10"   
  } 
]

感谢您提供进一步的建议。 我到处搜索并尝试错误,仍然无法解决。 感谢您的建议和支持。 谢谢

您应该能够像字典一样访问这些值,例如:

ifile=open('source.json', 'r')
ofile=open('extract.json', 'w')
json_decode=json.load(ifile)
myresult=[]
for item in json_decode:
    mydict={}
    mydict['sID']=item['Ls id']
    my_dict['dID']=item['items']['Link ID']['Metric']['Link Type']
    mydict['type']=item['Type']
    myresult.append(mydict)
myjson=json.dumps(myresult, ofile)
ofile.write(myjson)
ofile.close()

这对您有用吗? 如果没有,您遇到什么错误?

您需要遍历设备,然后遍历设备['items']

import json

with open('source.json', 'r') as ifile:
    json_data=json.load(ifile)

my_result=[]

for device in json_data:
    for item in device.get('items', []):
        my_dict={}
        my_dict['type'] = device.get('Type')
        my_dict['sID'] = device.get('Ls id')
        my_dict['dID'] = item.get('Link ID')
        my_dict['Link Type'] = item.get('Link Type')
        my_dict['Metric'] = item.get('Metric')
        my_result.append(my_dict)

with open('extract.json', 'w') as ofile:
    json.dump(my_result, ofile, indent=4)

对于更结构化的代码,您可能需要定义一个以设备/项目作为参数的函数,对其进行解析并返回字典/字典的列表。

首先,您将在item['items']中获得一个列表。 您需要确定是否需要保存该列表中的所有可用值。

其次,您尝试一次访问一个字典中的多个属性,但是链接了get命令。 但是,该代码尝试将其视为嵌套dict,并会遇到数据类型错误。

第三,您实际上不需要键入get ,更干净的版本是仅使用方括号表示法。

假设您需要为item['items']列表中的每个项目创建一个新的dict,那么解决方案将如下所示:

import json
s = '''
[
  {
    "Ls age": "201",
    "items": [
      {
        "Link ID": "1.1.1.2",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.4",
        "Link Type": "P-2-P",
        "Metric": "1",
        "Data": "192.168.100.34"
      },
      {
        "Link ID": "192.168.100.33",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.1",
        "Link Type": "P-2-P",
        "Metric": "1",
        "Data": "192.168.100.53"
      }
    ],
    "Len": "84",
    "Ls id": "1.1.1.2",
    "Adv rtr": "1.1.1.2",
    "Type": "Router",
    "Link count": "5"
  },
  {
    "Ls age": "1699",
    "seq#": "80008d72",
    "items": [
      {
        "Link ID": "1.1.1.1",
        "Link Type": "StubNet",
        "Metric": "1",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.1",
        "Link Type": "StubNet",
        "Metric": "12",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.3",
        "Link Type": "P-2-P",
        "Metric": "10",
        "Data": "192.168.100.26"
      },
      {
        "Link ID": "192.168.100.25",
        "Link Type": "StubNet",
        "Metric": "10",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      },
      {
        "Link ID": "1.1.1.2",
        "Link Type": "P-2-P",
        "Metric": "10",
        "Data": "192.168.100.54"
      },
      {
        "Link ID": "192.168.100.53",
        "Link Type": "StubNet",
        "Metric": "10",
        "Data": "255.255.255.255",
        "Priority": "Medium"
      }
    ],
    "Len": "96",
    "Ls id": "1.1.1.1",
    "chksum": "0x16fc",
    "Adv rtr": "1.1.1.1",
    "Type": "Router",
    "Options": "ASBR  E",
    "Link count": "6"
  }
]
'''
input_lst = json.loads(s)
myresult=[]
for item in input_lst:
    mydict={}
    mydict_sID = item['Ls id']
    mydict_type = item['Type']
    temp = []
    for x in item['items']:
        mydict={'Ls id': mydict_sID,
                'Type': mydict_type,
                'Link ID': x['Link ID'],
                'Metric': x['Metric'],
                'Link Type': x['Link Type']
                }
        temp.append(mydict)
    myresult.extend(temp)

确保根据需要更改用于读取字符串的代码行。

问题在于item['items']也是一个列表,因此您需要一个内部循环来处理其所有元素。 此外,您必须分别提取每个值:

for item in json_decode:
    for sub in item.get('items'):
        mydict={}
        mydict['type']=item.get('Type')
        mydict['sID']=item.get('Ls id')
        mydict['dID']=sub.get('Link ID')
        mydict['Link Type']=sub.get('Link Type')
        mydict['Metric']=sub.get('Metric')
        myresult.append(mydict)

要处理列表的嵌套对象的元素,您需要使用其他循环,例如,

import json

ifile = 'source.json'
ofile = 'extract.json'

myresult = []
with open(ifile, 'r') as sf:
   json_decode = json.load(sf)
   for item in json_decode:
       for sub_item in item.get('items', []):
           myresult.append(dict(type=item.get('Type'),
                                sID=item.get('Ls id', ''),
                                dID=sub_item.get('Link ID'),
                                LinkType=sub_item.get('Link Type'),
                                Metric=sub_item.get('Metric')
                                )
                           )

with open(ofile, 'w') as of:
    of.write(json.dumps(myresult, indent=4))

或使用列表理解的略微缩写版本:

import json

ifile = 'source.json'
ofile = 'extract.json'

with open(ifile, 'r') as sf:
    json_decode = json.load(sf)
    myresult = [dict(type=item.get('Type'), 
                     sID=item.get('Ls id', ''), 
                     dID=sub_item.get('Link ID'),
                     LinkType=sub_item.get('Link Type'), 
                     Metric=sub_item.get('Metric')) for item in json_decode 
                for sub_item in item.get('items', [])]

with open(ofile, 'w') as of:
    of.write(json.dumps(myresult, indent=4))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM