简体   繁体   English

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

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

I'm having difficulty to get some data from my json file. 我很难从json文件中获取一些数据。 I'm able to get some of the data but when I want to dig more in details I'm getting error and stuck no where. 我能够获得一些数据,但是当我想进一步挖掘细节时,我会出错并且没有卡住。

Running the script below return an error 运行下面的脚本返回错误

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

I know its a list but I'm not sure how to get the rest of the object list. 我知道它的列表,但是我不确定如何获取其余的对象列表。

Script 脚本

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()

source Json file 源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"
  }
]

Expected to have result as below 预期结果如下

[
  {
    "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"   
  } 
]

Appreciate to advise how could proceed further. 感谢您提供进一步的建议。 I have search around and try error and still no able to resolve it. 我到处搜索并尝试错误,仍然无法解决。 Appreciate your advise and support. 感谢您的建议和支持。 Thank you 谢谢

You should be able to access the values like a dictionary, for example: 您应该能够像字典一样访问这些值,例如:

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()

Does this work for you? 这对您有用吗? If not, what errors are you running into? 如果没有,您遇到什么错误?

you need to iterate over devices and then over device['items'] 您需要遍历设备,然后遍历设备['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)

For more structured code you may want to define a function(s) that takes device/item as argument, parse it and return a list of dicts/dict 对于更结构化的代码,您可能需要定义一个以设备/项目作为参数的函数,对其进行解析并返回字典/字典的列表。

First, you are getting a list in item['items'] . 首先,您将在item['items']中获得一个列表。 You need to decide whether you need to save all values available inside that list or not. 您需要确定是否需要保存该列表中的所有可用值。

Second, you are trying to access multiple attributes in a dict at once, but you're chaining the get commands. 其次,您尝试一次访问一个字典中的多个属性,但是链接了get命令。 The code however attempts to treat it like a nested dict, and would run into datatype errors. 但是,该代码尝试将其视为嵌套dict,并会遇到数据类型错误。

Third, you don't actually need to type get like that, a cleaner version is to just use the square bracket notation. 第三,您实际上不需要键入get ,更干净的版本是仅使用方括号表示法。

Assuming you need to create a new dict for each of the items in the list of item['items'] a solution would look something like this: 假设您需要为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)

Make sure you change the code lines that i used to read the string as necessary. 确保根据需要更改用于读取字符串的代码行。

The problem is that item['items'] is also a list so you need an inner loop to process all of its elements. 问题在于item['items']也是一个列表,因此您需要一个内部循环来处理其所有元素。 Furthermore you must extract individually each value: 此外,您必须分别提取每个值:

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)

to process the elements of a nested object of the list, you need to use an additional loop, for example, 要处理列表的嵌套对象的元素,您需要使用其他循环,例如,

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))

or a slightly abbreviated version using list comprehension: 或使用列表理解的略微缩写版本:

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