回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我正在迭代一个复杂的json对象,它作为字典加载到python中。下面是json文件的示例。对感兴趣的数据进行了注释。在</p>
<pre><code>{
"name":"ns1:timeSeriesResponseType",
"nil":false,
"value":{
"queryInfo":{ },
"timeSeries":[
{
"variable":{ },
"values":[
{
"qualifier":[ ],
"censorCode":[ ],
"value":[
{
"codedVocabularyTerm":null,
"censorCode":null,
"offsetTypeID":null,
"accuracyStdDev":null,
"timeOffset":null,
"qualifiers":[
"P", # data of interest
"Ice" # data of interest
],
"qualityControlLevelCode":null,
"sampleID":null,
"dateTimeAccuracyCd":null,
"methodCode":null,
"codedVocabulary":null,
"sourceID":null,
"oid":null,
"dateTimeUTC":null,
"offsetValue":null,
"metadataTime":null,
"labSampleCode":null,
"methodID":null,
"value":"-999999",
"dateTime":"2015-02-24T03:30:00.000-05:00",
"offsetTypeCode":null,
"sourceCode":null
},
{
"codedVocabularyTerm":null,
"censorCode":null,
"offsetTypeID":null,
"accuracyStdDev":null,
"timeOffset":null,
"qualifiers":[ ],
"qualityControlLevelCode":null,
"sampleID":null,
"dateTimeAccuracyCd":null,
"methodCode":null,
"codedVocabulary":null,
"sourceID":null,
"oid":null,
"dateTimeUTC":null,
"offsetValue":null,
"metadataTime":null,
"labSampleCode":null,
"methodID":null,
"value":"-999999", # data of interest
"dateTime":"2015-02-24T04:00:00.000-05:00", # data of interest
"offsetTypeCode":null,
"sourceCode":null
}
],
"sample":[ ],
"source":[ ],
"offset":[ ],
"units":null,
"qualityControlLevel":[ ],
"method":[ ]
}
],
"sourceInfo":{ },
"name":"USGS:03193000:00060:00011"
},
{ }, # more data need is stored in here
{ }, # more data need is stored in here
{ } # more data need is stored in here
]
},
"declaredType":"org.cuahsi.waterml.TimeSeriesResponseType",
"scope":"javax.xml.bind.JAXBElement$GlobalScope",
"globalScope":true,
"typeSubstituted":false
}
</code></pre>
<p>下面是我的代码,用于单步执行/遍历字典以获取我想要的数据,并将其存储在一个格式更简单的字典中:</p>
^{pr2}$
<p>我的问题是——作为python的新手,有人能指出我代码中明显的低效吗?我相信在很多年的时间里,<或者我的json文件的值都是无效的。有没有一种简单的方法可以搜索并返回键:值对从这样一个分层字典,字典列表里面有字典列表吗?在</p>
<p><strong>编辑:</strong></p>
<p>基于@Alex Martelli提供的解决方案,这里是代码的新的、更高效的精简版本:</p>
<pre><code># Building the output dictionary
for key in result["value"]["timeSeries"]:
if "values" in key:
for key2 in key.get("values"):
if "value" in key2:
for key3 in key2.get("value"):
if "value" in key3:
valueList.<a href="https://www.cnpython.com/list/append" class="inner-link">append</a>(key3.get("value"))
if "dateTime" in key3:
dateTimeList.append(key3.get("dateTime"))
if "qualifiers" in key3:
qualifiersList.append(key3.get("qualifiers"))
if "name" in key:
outputList.append(key.get("name"))
outputDict[key.get("name")]={"dateTime":None, "values":None, "qualifiers":None}
outputDict[key.get("name")]["dateTime"] = dateTimeList[:] # passing the items in the list rather
outputDict[key.get("name")]["values"] = valueList[:] # than a reference to the list so the delete works
outputDict[key.get("name")]["qualifiers"] = qualifiersList[:] # than a reference to the list so the delete works
del dateTimeList[:]
del valueList[:]
del qualifiersList[:]
</code></pre>
<p>工作原理相同,删除了4行代码。运行时间更快。不错。在</p>
<p><strong>编辑:</strong></p>
<p>基于@Two Bit Alchemist提出的解决方案,该方案同样有效:</p>
<pre><code># Building the output dictionary
for key in result["value"]["timeSeries"]:
print key
for value in key["values"][0]["value"]:
# qualifiers is a list containing ["P", "Ice"]
qualifiersList.append(value['qualifiers'])
valueList.append(value['value'])
dateTimeList.append(value['dateTime'])
if "name" in key:
outputList.append(key.get("name"))
outputDict[key.get("name")]={"dateTime":None, "values":None, "qualifiers":None}
outputDict[key.get("name")]["dateTime"] = dateTimeList[:] # passing the items in the list rather
outputDict[key.get("name")]["values"] = valueList[:] # than a reference to the list so the delete works
outputDict[key.get("name")]["qualifiers"] = qualifiersList[:] # than a reference to the list so the delete works
del dateTimeList[:]
del valueList[:]
del qualifiersList[:]
</code></pre>
<p>我看到的唯一问题是,我从来没有完全确定[“值”]列表中的第一个位置是我想要的。而且我丢失了“if”语句提供的检查,这些检查应该确保如果从错误的查询语句返回值时不会引入错误。在</p>
<p><strong>编辑:</strong></p>
<pre><code>try:
# requests.get returns a "file-like" object
# in this case it is a JSON object because of the settings in the query
response = requests.get(url=query)
# if-else ladder that only performs the parsing of the returned JSON object
# when the HTTP status code indicates a successful query execution
if(response.status_code == 200):
# parsing the
result = response.json()
# Setting up blank variables to store results
outputDict = {}
outputList = []
dateTimeList = []
valueList = []
qualifiersList = []
# Building the output dictionary
for key in result["value"]["timeSeries"]:
print key
for value in key["values"][0]["value"]:
# qualifiers is a list containing ["P", "Ice"]
qualifiersList.append(value['qualifiers'])
valueList.append(value['value'])
dateTimeList.append(value['dateTime'])
# OLD CODE
# if "values" in key:
# for key2 in key.get("values"):
# if "value" in key2:
# for key3 in key2.get("value"):
# if "value" in key3:
# valueList.append(key3.get("value"))
# if "dateTime" in key3:
# dateTimeList.append(key3.get("dateTime"))
# if "qualifiers" in key3:
# qualifiersList.append(key3.get("qualifiers"))
if "name" in key:
outputList.append(key.get("name"))
outputDict[key.get("name")]={"dateTime":None, "values":None, "qualifiers":None}
outputDict[key.get("name")]["dateTime"] = dateTimeList[:] # passing the items in the list rather
outputDict[key.get("name")]["values"] = valueList[:] # than a reference to the list so the delete works
outputDict[key.get("name")]["qualifiers"] = qualifiersList[:] # than a reference to the list so the delete works
del dateTimeList[:]
del valueList[:]
del qualifiersList[:]
# Tracking how long it took to process the data
elapsed = time.time() - now
print "Runtime: " + str(elapsed)
out = {"Status": 'ok', "Results": [[{"myResult": outputDict}]]}
elif(response.status_code == 400):
raise Exception("Bad Request, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
elif(response.status_code== 403):
raise Exception("Access Forbidden, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
elif(response.status_code == 404):
raise Exception("Gage location(s) not Found, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
elif(response.status_code == 500):
raise Exception("Internal Server Error, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
elif(response.status_code == 503):
raise Exception("Service Unavailable, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
else:
raise Exception("Unknown Response, "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
except:
out = {"Status": 'Error', "Message": str(sys.exc_info()[1])}
print out
</code></pre>