如何获取复杂数组中列表的第二小值?公交API场景问题处理
解决公交出发时间剩余分钟数为0时的无效显示问题
问题背景
我用以下代码从API获取指定线路最早公交出发时间的剩余分钟数:
soonestDepartureTimeUnix = min(item["departure_time"] for item in tsl105513Route2["itineraries"][0]["schedule_items"]) minutes = int((soonestDepartureTimeUnix - (time.time()))/60)
但当minutes为0时,这个结果对路人没有实际意义,需要获取第二早的出发时间来替代。
API响应结构
{ "route_departures": [ { "global_route_id": "TSL:105513", "itineraries": [ { "branch_code": "", "direction_headsign": "*******", "direction_id": 1, "headsign": "******", "merged_headsign": "******", "schedule_items": [ { "departure_time": 1713461520, "is_cancelled": false, "is_real_time": false, "rt_trip_id": "13811798", "scheduled_departure_time": 1713461520, "trip_search_key": "TSL:45069396:369:5:15", "wheelchair_accessible": 1 }, { "departure_time": 1713463320, "is_cancelled": false, "is_real_time": false, "rt_trip_id": "13811799", "scheduled_departure_time": 1713463320, "trip_search_key": "TSL:45069396:369:5:16", "wheelchair_accessible": 1 }, { "departure_time": 1713465120, "is_cancelled": false, "is_real_time": false, "rt_trip_id": "13811800", "scheduled_departure_time": 1713465120, "trip_search_key": "TSL:45069396:369:5:17", "wheelchair_accessible": 1 } ] } ], "mode_name": "Bus", "real_time_route_id": "30048", "route_color": "2a61a0", "route_long_name": "******", "route_network_id": "TransLink|Vancouver", "route_network_name": "TransLink", "route_short_name": "**8", "route_text_color": "ffffff", "route_type": 3, "sorting_key": "***", "tts_long_name": "*****", "tts_short_name": "*** " } ] }
尝试过的错误方案
- 方案1:直接跳转
itineraries下一项,触发list item out of range错误
if minutes < 1: soonestDepartureTimeUnix = (item["departure_time"] for item in tsl105513Route2["itineraries"][1]["schedule_items"]) minutes = int((soonestDepartureTimeUnix - (time.time()))/60)
- 方案2:直接取
schedule_items第二个元素,触发生成器与浮点数无法相减错误
if minutes < 1: soonestDepartureTimeUnix = (item["departure_time"] for item in tsl105513Route2["itineraries"][0]["schedule_items"][1]) minutes = int((soonestDepartureTimeUnix - (time.time()))/60)
- 方案3:参考第二小值获取方案,仍返回0
if minutes < 1: soonestDepartureTimeUnix2 = min(item["departure_time"] for item in tsl105513Route2["itineraries"][0]["schedule_items"] if item != soonestDepartureTimeUnix) minutes = int((soonestDepartureTimeUnix2 - (time.time()))/60)
正确解法及错误分析
错误原因拆解
- 方案1:
itineraries数组仅包含1个元素(索引0),访问索引1必然触发越界 - 方案2:
schedule_items[1]是单个字典对象,用生成器遍历会迭代字典的键名,而非时间值,导致类型不匹配 - 方案3:
item != soonestDepartureTimeUnix是将字典与时间戳对比,结果永远为True,因此仍取到原最小值
方法1:自动筛选有效出发时间
提取所有出发时间并排序,依次过滤已过时间,取第一个有效且非0的时间:
import time # 提取目标线路的所有发车时间并排序 schedule_items = tsl105513Route2["itineraries"][0]["schedule_items"] sorted_departures = sorted(item["departure_time"] for item in schedule_items) current_time = time.time() target_minutes = None for dep_time in sorted_departures: minutes = int((dep_time - current_time) / 60) if minutes > 0: target_minutes = minutes break elif minutes == 0: # 即将发车,可选择提示"即将发车"或跳过取后续车次 continue # 处理无后续车次的情况 if target_minutes is None: print("暂无后续发车班次") else: print(f"下一班车还有 {target_minutes} 分钟")
方法2:针对最早时间已过的场景取第二小值
先获取最早时间,若已过则排除后取剩余最小值:
import time schedule_items = tsl105513Route2["itineraries"][0]["schedule_items"] all_departures = [item["departure_time"] for item in schedule_items] current_time = time.time() # 先计算最早车次的剩余时间 soonest_dep = min(all_departures) minutes = int((soonest_dep - current_time) / 60) # 若最早车次已过或即将发车,取第二早车次 if minutes < 1: remaining_departures = [t for t in all_departures if t != soonest_dep] if remaining_departures: second_soonest = min(remaining_departures) minutes = int((second_soonest - current_time) / 60) else: minutes = None print(f"下一班车剩余时间:{minutes} 分钟" if minutes is not None else "暂无后续班次")
内容的提问来源于stack exchange,提问作者WesternBiscuit
相关产品推荐
相关产品推荐

