我有一个python程序调用一个API,它接收如下结果:
{
"result": [
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "3"
},
{
"company" : "BMW",
"model" : "7"
},
{
"company" : "AUDI",
"model" : "A3"
},
{
"company" : "AUDI",
"model" : "A7"
},
]
}现在,我的任务是在JSON输出中确定列表中元素的出现次数,并对它们进行分组。预期输出应如下所示:
{
"BMW" :
{
"5series" : 3,
"3series" : 1,
"7series" : 1,
},
"AUDI" :
{
"A3" : 1,
"A7" : 1,
},
"MERCEDES":
{
"EClass" : 0,
"SClass" : 0
}
}我需要从元素列表中找到"company“。这将包括有时可能不在JSON响应中的名称,那么预期的输出应该包括该名称作为0。“模型”名称(3,5,7,A3等..,)是固定的,因此我们知道这些名称可能在json api响应中,也可能不在json api响应中。
例如:列表中有3个公司名称,代码如下。- companyname = "BMW,"AUDI","MERCEDES“。但是,有时JSON API响应可能没有一个或多个元素。在这种情况下,缺少"MERCEDES”,但最终输出应该包含"MERCEDES“,值为0。
这是我到目前为止尝试过的:
def modelcount():
companyname= ["BMW","AUDI","MERCEDES"]
url = apiurl
#Send Request
apiresponse = requests.get(url, auth=(user, password), headers=headers, proxies=proxies)
# Decode the JSON response into a dictionary and use the data
data = apiresponse.json()
print(len(data['result']))
3series= 0
5series= 0
7series= 0
A3=0
A7=0
EClass = 0
SClass = 0
modelcountjson = {}
for name in companyname:
for item in data['result']:
models= {}
if item['company'] == name:
if item['model'] == 3:
3series = 3series + 1
elif item['model'] == 5:
5series = 5series + 1
elif item['model'] == 7:
7series = 7series + 1
models['3series'] = 3series
models['5series'] = 5series
models['7series'] = 7series
#I still haven't written AUDI, MERCEDES above. This is where i feel i am writing inefficiently.
modelcountjson[name] = models
return jsonify(modelcountjson)随着模型数量的增长,我担心代码会因为许多for循环而变得冗余,并可能导致性能开销。我正在寻找以最有效的方式实现最终结果的帮助。
非常感谢你的帮助。
发布于 2020-03-16 00:49:28
你可以把代码和配置分开一点:
conf = {
'BMW': {'format': '{}series', 'keys': ['3', '5', '7']},
'AUDI': {'format': '{}', 'keys': ['A3', 'A7']},
'MERCEDES': {'format': '{}Class', 'keys': ['E', 'S']},
}
def modelcount():
# retrieve `data`
# ...
result = {
k: {
v['format'].format(key): 0 for key in v['keys']
} for k, v in conf.items()
}
for car in data['result']:
com = car['company']
mod = car['model']
key = conf[com]['format'].format(mod)
result[com][key] += 1
for com in result:
result[com]['Total'] = sum(result[com].values())
return result
>>> modelcount()
{'BMW': {'3series': 1, '5series': 3, '7series': 1},
'AUDI': {'A3': 1, 'A7': 1},
'MERCEDES': {'EClass': 0, 'SClass': 0}}这样,对于更多的公司和模型,您将只需触摸conf,而不是代码。它的时间复杂度是O(m+n),其中m是不同车型的总数,n是API响应中的汽车数量。
发布于 2020-03-16 00:55:30
直接使用JSON风格的字典和列表的一个有用的包是toolz (有关更多详细信息,请参阅documentation )。这样,您可以简洁地对数据进行分组,并计算每个模型的出现次数,同时单独处理可能丢失的数据:
from toolz import itertoolz
result = {
"result": [
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "5"
},
{
"company" : "BMW",
"model" : "3"
},
{
"company" : "BMW",
"model" : "7"
},
{
"company" : "AUDI",
"model" : "A3"
},
{
"company" : "AUDI",
"model" : "A7"
},
]
}
final_output = {}
grouped_result = itertoolz.groupby('company', result['result'])
if 'MERCEDES' not in grouped_result:
final_output['MERCEDES'] = {
'EClass': 0,
'SClass': 0
}
for key, value in grouped_result.items():
models = itertoolz.pluck('model', value)
final_output[key] = itertoolz.frequencies(models) 输出结果为:
{'AUDI': {'A3': 1, 'A7': 1}, 'BMW': {'3': 1, '5': 3, '7': 1}, 'MERCEDES': {'EClass': 0, 'SClass': 0}}https://stackoverflow.com/questions/60694947
复制相似问题