我是Python的新手,所以我正在尝试猜测并检查语法。我有一个JSON对象,我从API GET返回:
result = requests.get(mbta_url)
data = result.json()
那个对象很大,我只需要一些数据点。不幸的是,API不允许我使用params过滤掉请求。
我的问题是:我如何过滤掉这个对象,这样它才会返回结果,其中mode.route.route_id =“Orange”AND mode.route.direction.direction_name =“Southbound”
以下是我要回的数据:
{
"stop_id": "place-bbsta",
"stop_name": "Back Bay",
"mode": [
{
"route_type": "1",
"mode_name": "Subway",
"route": [
{
"route_id": "Orange",
"route_name": "Orange Line",
"direction": [
{
"direction_id": "0",
"direction_name": "Southbound",
"trip": [
{
"trip_id": "33296516",
"trip_name": "2:50 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469300",
"sch_dep_dt": "1490469300",
"pre_dt": "1490469359",
"pre_away": "283",
"vehicle": {
"vehicle_id": "544CBD7E",
"vehicle_lat": "42.35881",
"vehicle_lon": "-71.05782",
"vehicle_bearing": "175",
"vehicle_timestamp": "1490468990",
"vehicle_label": "1229"
}
},
{
"trip_id": "33296517",
"trip_name": "2:59 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469840",
"sch_dep_dt": "1490469840",
"pre_dt": "1490469726",
"pre_away": "650",
"vehicle": {
"vehicle_id": "544CB782",
"vehicle_lat": "42.37376",
"vehicle_lon": "-71.07041",
"vehicle_bearing": "120",
"vehicle_timestamp": "1490469027",
"vehicle_label": "1245"
}
},
{
"trip_id": "33296518",
"trip_name": "3:07 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490470320",
"sch_dep_dt": "1490470320",
"pre_dt": "1490470307",
"pre_away": "1231",
"vehicle": {
"vehicle_id": "544CBE8D",
"vehicle_lat": "42.42462",
"vehicle_lon": "-71.07519",
"vehicle_bearing": "200",
"vehicle_timestamp": "1490469053",
"vehicle_label": "1209"
}
}
]
},
{
"direction_id": "1",
"direction_name": "Northbound",
"trip": [
{
"trip_id": "33296558",
"trip_name": "2:59 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490469120",
"sch_dep_dt": "1490469120",
"pre_dt": "1490469077",
"pre_away": "1",
"vehicle": {
"vehicle_id": "544CBD65",
"vehicle_lat": "42.34571",
"vehicle_lon": "-71.07814",
"vehicle_bearing": "40",
"vehicle_timestamp": "1490469035",
"vehicle_label": "1288"
}
},
{
"trip_id": "33296561",
"trip_name": "3:08 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490469660",
"sch_dep_dt": "1490469660",
"pre_dt": "1490469628",
"pre_away": "552",
"vehicle": {
"vehicle_id": "544CBD69",
"vehicle_lat": "42.31318",
"vehicle_lon": "-71.10594",
"vehicle_bearing": "25",
"vehicle_timestamp": "1490469061",
"vehicle_label": "1263"
}
},
{
"trip_id": "33296564",
"trip_name": "3:16 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490470140",
"sch_dep_dt": "1490470140",
"pre_dt": "1490470085",
"pre_away": "1009"
},
{
"trip_id": "33296567",
"trip_name": "3:25 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490470680",
"sch_dep_dt": "1490470680",
"pre_dt": "1490470672",
"pre_away": "1596"
},
{
"trip_id": "33296570",
"trip_name": "3:34 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490471220",
"sch_dep_dt": "1490471220",
"pre_dt": "1490471166",
"pre_away": "2090"
},
{
"trip_id": "33296541",
"trip_name": "3:43 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490471760",
"sch_dep_dt": "1490471760",
"pre_dt": "1490471706",
"pre_away": "2630"
},
{
"trip_id": "33296545",
"trip_name": "3:51 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490472240",
"sch_dep_dt": "1490472240",
"pre_dt": "1490472185",
"pre_away": "3109"
}
]
}
]
}
]
},
{
"route_type": "2",
"mode_name": "Commuter Rail",
"route": [
{
"route_id": "CR-Franklin",
"route_name": "Franklin Line",
"direction": [
{
"direction_id": "0",
"direction_name": "Outbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1711",
"trip_name": "1711 (3:20 pm from South Station)",
"trip_headsign": "Forge Park/495",
"sch_arr_dt": "1490469900",
"sch_dep_dt": "1490469900",
"pre_dt": "1490469890",
"pre_away": "814",
"vehicle": {
"vehicle_id": "1827",
"vehicle_lat": "42.3515701293945",
"vehicle_lon": "-71.0551605224609",
"vehicle_bearing": "200",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468918",
"vehicle_label": "1827"
}
}
]
},
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1710",
"trip_name": "1710 (2:35 pm from Forge Park/495)",
"trip_headsign": "South Station",
"sch_arr_dt": "1490470380",
"sch_dep_dt": "1490470380",
"pre_dt": "1490470507",
"pre_away": "1431",
"vehicle": {
"vehicle_id": "1507",
"vehicle_lat": "42.1975784301758",
"vehicle_lon": "-71.1965026855469",
"vehicle_bearing": "7",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468913",
"vehicle_label": "1507"
}
}
]
}
]
},
{
"route_id": "CR-Needham",
"route_name": "Needham Line",
"direction": [
{
"direction_id": "0",
"direction_name": "Outbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1609",
"trip_name": "1609 (3:10 pm from South Station)",
"trip_headsign": "Needham Heights",
"sch_arr_dt": "1490469300",
"sch_dep_dt": "1490469300",
"pre_dt": "1490469268",
"pre_away": "192",
"vehicle": {
"vehicle_id": "1531",
"vehicle_lat": "42.3505516052246",
"vehicle_lon": "-71.055908203125",
"vehicle_bearing": "200",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468911",
"vehicle_label": "1531"
}
}
]
},
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1610",
"trip_name": "1610 (4:00 pm from Needham Heights)",
"trip_headsign": "South Station",
"sch_arr_dt": "1490474040",
"sch_dep_dt": "1490474040",
"pre_dt": "1490474006",
"pre_away": "4930"
}
]
}
]
},
{
"route_id": "CR-Providence",
"route_name": "Providence/Stoughton Line",
"direction": [
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1810",
"trip_name": "1810 (2:56 pm from Providence)",
"trip_headsign": "South Station",
"sch_arr_dt": "1490472120",
"sch_dep_dt": "1490472120",
"pre_dt": "1490472187",
"pre_away": "3111",
"vehicle": {
"vehicle_id": "1707",
"vehicle_lat": "41.8979415893555",
"vehicle_lon": "-71.3540573120117",
"vehicle_bearing": "86",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468928",
"vehicle_label": "1707"
}
}
]
}
]
},
{
"route_id": "CR-Worcester",
"route_name": "Framingham/Worcester Line",
"direction": [
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "CR-Saturday-Fall-16-1508",
"trip_name": "1508 (2:30 pm from Worcester)",
"trip_headsign": "South Station",
"sch_arr_dt": "1490471700",
"sch_dep_dt": "1490471700",
"pre_dt": "1490471802",
"pre_away": "2726",
"vehicle": {
"vehicle_id": "1801",
"vehicle_lat": "42.2759819030762",
"vehicle_lon": "-71.4203491210938",
"vehicle_bearing": "69",
"vehicle_speed": "4",
"vehicle_timestamp": "1490468935",
"vehicle_label": "1801"
}
}
]
}
]
}
]
},
{
"route_type": "3",
"mode_name": "Bus",
"route": [
{
"route_id": "10",
"route_name": "10",
"direction": [
{
"direction_id": "0",
"direction_name": "Outbound",
"trip": [
{
"trip_id": "33647996",
"trip_name": "3:17 pm from Saint James Ave @ Dartmouth St to City Point Bus Terminal",
"trip_headsign": "City Point via South Bay Center",
"sch_arr_dt": "1490469540",
"sch_dep_dt": "1490469540",
"pre_dt": "1490469747",
"pre_away": "671"
},
{
"trip_id": "33647982",
"trip_name": "3:39 pm from Saint James Ave @ Dartmouth St to City Point Bus Terminal",
"trip_headsign": "City Point via South Bay Center",
"sch_arr_dt": "1490470860",
"sch_dep_dt": "1490470860",
"pre_dt": "1490470858",
"pre_away": "1782"
}
]
},
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "33647998",
"trip_name": "2:32 pm from City Point Bus Terminal to Saint James Ave @ Dartmouth St",
"trip_headsign": "Copley via South Bay Center",
"sch_arr_dt": "1490468880",
"sch_dep_dt": "1490468880",
"pre_dt": "1490469438",
"pre_away": "362",
"vehicle": {
"vehicle_id": "y2160",
"vehicle_lat": "42.3370819091797",
"vehicle_lon": "-71.0714645385742",
"vehicle_bearing": "51",
"vehicle_speed": "0",
"vehicle_timestamp": "1490469034",
"vehicle_label": "2160"
}
},
{
"trip_id": "33647979",
"trip_name": "2:55 pm from City Point Bus Terminal to Saint James Ave @ Dartmouth St",
"trip_headsign": "Copley via South Bay Center",
"sch_arr_dt": "1490470260",
"sch_dep_dt": "1490470260",
"pre_dt": "1490470085",
"pre_away": "1009",
"vehicle": {
"vehicle_id": "y1779",
"vehicle_lat": "42.3294982910156",
"vehicle_lon": "-71.061149597168",
"vehicle_bearing": "144",
"vehicle_speed": "0",
"vehicle_timestamp": "1490469009",
"vehicle_label": "1779"
}
},
{
"trip_id": "33648025",
"trip_name": "3:17 pm from City Point Bus Terminal to Saint James Ave @ Dartmouth St",
"trip_headsign": "Copley via South Bay Center",
"sch_arr_dt": "1490471580",
"sch_dep_dt": "1490471580",
"pre_dt": "1490471507",
"pre_away": "2431"
},
{
"trip_id": "33648010",
"trip_name": "3:39 pm from City Point Bus Terminal to Saint James Ave @ Dartmouth St",
"trip_headsign": "Copley via South Bay Center",
"sch_arr_dt": "1490472900",
"sch_dep_dt": "1490472900",
"pre_dt": "1490472729",
"pre_away": "3653"
}
]
}
]
},
{
"route_id": "39",
"route_name": "39",
"direction": [
{
"direction_id": "0",
"direction_name": "Outbound",
"trip": [
{
"trip_id": "33788263",
"trip_name": "3:15 pm from Back Bay Station to Forest Hills Station",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469300",
"sch_dep_dt": "1490469300",
"pre_dt": "1490469300",
"pre_away": "224"
},
{
"trip_id": "33788273",
"trip_name": "3:25 pm from Back Bay Station to Forest Hills Station",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469900",
"sch_dep_dt": "1490469900",
"pre_dt": "1490469900",
"pre_away": "824"
},
{
"trip_id": "33788283",
"trip_name": "3:35 pm from Back Bay Station to Forest Hills Station",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490470500",
"sch_dep_dt": "1490470500",
"pre_dt": "1490470882",
"pre_away": "1806"
}
]
},
{
"direction_id": "1",
"direction_name": "Inbound",
"trip": [
{
"trip_id": "33788252",
"trip_name": "2:35 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490468940",
"sch_dep_dt": "1490468940",
"pre_dt": "1490469286",
"pre_away": "210",
"vehicle": {
"vehicle_id": "y1269",
"vehicle_lat": "42.3499755859375",
"vehicle_lon": "-71.0776748657227",
"vehicle_bearing": "72",
"vehicle_speed": "0",
"vehicle_timestamp": "1490469032",
"vehicle_label": "1269"
}
},
{
"trip_id": "33788262",
"trip_name": "2:45 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490469540",
"sch_dep_dt": "1490469540",
"pre_dt": "1490469850",
"pre_away": "774",
"vehicle": {
"vehicle_id": "y1251",
"vehicle_lat": "42.3383369445801",
"vehicle_lon": "-71.09375",
"vehicle_bearing": "59",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468986",
"vehicle_label": "1251"
}
},
{
"trip_id": "33788272",
"trip_name": "2:55 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490470080",
"sch_dep_dt": "1490470080",
"pre_dt": "1490470882",
"pre_away": "1806",
"vehicle": {
"vehicle_id": "y1271",
"vehicle_lat": "42.3093566894531",
"vehicle_lon": "-71.115592956543",
"vehicle_bearing": "0",
"vehicle_speed": "0",
"vehicle_timestamp": "1490469016",
"vehicle_label": "1271"
}
},
{
"trip_id": "33788282",
"trip_name": "3:05 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490470620",
"sch_dep_dt": "1490470620",
"pre_dt": "1490470966",
"pre_away": "1890",
"vehicle": {
"vehicle_id": "y1260",
"vehicle_lat": "42.3032569885254",
"vehicle_lon": "-71.1146392822266",
"vehicle_bearing": "351",
"vehicle_speed": "0",
"vehicle_timestamp": "1490468980",
"vehicle_label": "1260"
}
},
{
"trip_id": "33788292",
"trip_name": "3:15 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490471220",
"sch_dep_dt": "1490471220",
"pre_dt": "1490471891",
"pre_away": "2815"
},
{
"trip_id": "33788218",
"trip_name": "3:25 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490471820",
"sch_dep_dt": "1490471820",
"pre_dt": "1490472018",
"pre_away": "2942"
},
{
"trip_id": "33788230",
"trip_name": "3:35 pm from Forest Hills Station to Back Bay Station",
"trip_headsign": "Back Bay",
"sch_arr_dt": "1490472420",
"sch_dep_dt": "1490472420",
"pre_dt": "1490472675",
"pre_away": "3599"
}
]
}
]
}
]
}
],
我试图用这个来减少对象,但它在函数中出错:
#results
x = json.loads(data)
routes = x['mode'][0]['route_type']
这是我得到Heroku日志的错误:
TypeError:期望的字符串或缓冲区
答案 0 :(得分:2)
考虑将json视为嵌套字典/列表的集合。因此,遍历模式列表并有条件地仅选择 route_names (dict键),其值为 Orange Line 。然后,将此类内容附加到不断增长的 newdata 字典中。
下面使用OrderedDict()
来维护原始的键顺序,因为默认情况下字典不保持键顺序。但是,即使采用这种方法,较低的字典项也可能会重新排序。
from collections import OrderedDict
import json
# receive api request...into 'data' object...
# INITIALIZE NEW FILTERED DICTIONARY (RETAINING TOP LEVEL ITEMS)
newdata = OrderedDict({k:v for k,v in data.items() if k in ['stop_id', 'stop_name']})
newdata['mode'] = []
# ITERATE CONDITIONALLY KEEPING NEEDED SECTIONS
for i in data['mode']:
if i['route'][0]['route_name'] == 'Orange Line':
newdata['mode'].append(OrderedDict(i))
# OUTPUT TO FILE
with open('Output.json', 'w') as f:
f.write(json.dumps(newdata, indent=2))
<强>输出强>
{
"stop_id": "place-bbsta",
"stop_name": "Back Bay",
"mode": [
{
"route_type": "1",
"mode_name": "Subway",
"route": [
{
"route_id": "Orange",
"route_name": "Orange Line",
"direction": [
{
"direction_id": "0",
"direction_name": "Southbound",
"trip": [
{
"trip_id": "33296516",
"trip_name": "2:50 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469300",
"sch_dep_dt": "1490469300",
"pre_dt": "1490469359",
"pre_away": "283",
"vehicle": {
"vehicle_id": "544CBD7E",
"vehicle_lat": "42.35881",
"vehicle_lon": "-71.05782",
"vehicle_bearing": "175",
"vehicle_timestamp": "1490468990",
"vehicle_label": "1229"
}
},
{
"trip_id": "33296517",
"trip_name": "2:59 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490469840",
"sch_dep_dt": "1490469840",
"pre_dt": "1490469726",
"pre_away": "650",
"vehicle": {
"vehicle_id": "544CB782",
"vehicle_lat": "42.37376",
"vehicle_lon": "-71.07041",
"vehicle_bearing": "120",
"vehicle_timestamp": "1490469027",
"vehicle_label": "1245"
}
},
{
"trip_id": "33296518",
"trip_name": "3:07 pm from Oak Grove to Forest Hills Orange Line",
"trip_headsign": "Forest Hills",
"sch_arr_dt": "1490470320",
"sch_dep_dt": "1490470320",
"pre_dt": "1490470307",
"pre_away": "1231",
"vehicle": {
"vehicle_id": "544CBE8D",
"vehicle_lat": "42.42462",
"vehicle_lon": "-71.07519",
"vehicle_bearing": "200",
"vehicle_timestamp": "1490469053",
"vehicle_label": "1209"
}
}
]
},
{
"direction_id": "1",
"direction_name": "Northbound",
"trip": [
{
"trip_id": "33296558",
"trip_name": "2:59 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490469120",
"sch_dep_dt": "1490469120",
"pre_dt": "1490469077",
"pre_away": "1",
"vehicle": {
"vehicle_id": "544CBD65",
"vehicle_lat": "42.34571",
"vehicle_lon": "-71.07814",
"vehicle_bearing": "40",
"vehicle_timestamp": "1490469035",
"vehicle_label": "1288"
}
},
{
"trip_id": "33296561",
"trip_name": "3:08 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490469660",
"sch_dep_dt": "1490469660",
"pre_dt": "1490469628",
"pre_away": "552",
"vehicle": {
"vehicle_id": "544CBD69",
"vehicle_lat": "42.31318",
"vehicle_lon": "-71.10594",
"vehicle_bearing": "25",
"vehicle_timestamp": "1490469061",
"vehicle_label": "1263"
}
},
{
"trip_id": "33296564",
"trip_name": "3:16 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490470140",
"sch_dep_dt": "1490470140",
"pre_dt": "1490470085",
"pre_away": "1009"
},
{
"trip_id": "33296567",
"trip_name": "3:25 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490470680",
"sch_dep_dt": "1490470680",
"pre_dt": "1490470672",
"pre_away": "1596"
},
{
"trip_id": "33296570",
"trip_name": "3:34 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490471220",
"sch_dep_dt": "1490471220",
"pre_dt": "1490471166",
"pre_away": "2090"
},
{
"trip_id": "33296541",
"trip_name": "3:43 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490471760",
"sch_dep_dt": "1490471760",
"pre_dt": "1490471706",
"pre_away": "2630"
},
{
"trip_id": "33296545",
"trip_name": "3:51 pm from Forest Hills Orange Line to Oak Grove",
"trip_headsign": "Oak Grove",
"sch_arr_dt": "1490472240",
"sch_dep_dt": "1490472240",
"pre_dt": "1490472185",
"pre_away": "3109"
}
]
}
]
}
]
}
]
}
对于所有 sch_arr_dt 值,请有条件地沿着嵌套的dict / list集合向下走:
sch_arr_dt = []
for i in data['mode']:
if i['route'][0]['route_name'] == 'Orange Line':
if i['route'][0]['direction'][0]['direction_name'] == 'Southbound':
for s in i['route'][0]['direction'][0]['trip']:
sch_arr_dt.append(s['sch_arr_dt'])
print(sch_arr_dt)
# ['1490469300', '1490469840', '1490470320']
当然,作为芝加哥橘子线的狂热骑手,我不得不回答这个问题! =)