Python迭代JSON提取数据及订阅活跃用户费用计算方法
问题1:提取包含rider角色的用户名
你当前的循环写法针对单次查询场景已经是效率最高的实现,没有冗余计算,时间复杂度为O(N*K)(N为用户总数,K为单个用户的角色列表平均长度)。
如果需要更简洁的写法,可以用列表推导式:
rider_names = [user['name'] for user in users if 'rider' in user['roles']] # 打印结果 for name in rider_names: print(name)
如果需要频繁查询不同角色对应的用户,可以提前构建倒排索引,一次构建多次查询的效率会大幅提升:
from collections import defaultdict # 构建角色到用户名的倒排索引 role_index = defaultdict(list) for user in users: for role in user['roles']: role_index[role].append(user['name']) # 直接查询rider对应的用户 print(role_index.get('rider', []))
问题2:计算指定自然月的订阅费用
实现思路
- 先获取指定月份的总天数,计算单日人均订阅费 = 4 / 当月总天数
- 遍历当月每一天,统计当日活跃用户数:满足
当日日期 >= 激活日期且停用日期为None 或 当日日期 < 停用日期 - 计算当日费用,累加得到整月总费用,按要求格式输出
- 自动兼容用户列表为空的场景,此时所有日期的活跃用户数和总费用均为0
基础实现代码(适合小数据量)
import datetime import calendar def calculate_monthly_subscription(year: int, month: int, users: list) -> float: # 获取当月总天数 _, total_days = calendar.monthrange(year, month) daily_per_cost = 4 / total_days total_monthly_cost = 0.0 # 遍历当月每一天 for day in range(1, total_days + 1): current_date = datetime.date(year, month, day) active_user_count = 0 # 统计当日活跃用户 for user in users: act_date = user['activated_on'] deact_date = user['deactivated_on'] if current_date >= act_date and (deact_date is None or current_date < deact_date): active_user_count += 1 # 计算当日费用 daily_cost = active_user_count * daily_per_cost total_monthly_cost += daily_cost # 按要求格式输出 print(f"{current_date.strftime('%Y-%m-%d')} {active_user_count} active users * ${daily_per_cost:.9f} = ${daily_cost:.9f} (subtotal: ${total_monthly_cost:.9f})") return total_monthly_cost # 调用示例:计算2019年1月的费用 calculate_monthly_subscription(2019, 1, users2)
优化实现代码(适合大数据量)
如果用户量级很大,可以提前计算每个用户在当月的活跃时间段,避免每天遍历所有用户,时间复杂度从O(天数*用户数)降低到O(用户数):
import datetime import calendar def calculate_monthly_subscription_optimized(year: int, month: int, users: list) -> float: _, total_days = calendar.monthrange(year, month) month_start = datetime.date(year, month, 1) month_end = datetime.date(year, month, total_days) daily_per_cost = 4 / total_days total_monthly_cost = 0.0 # 初始化每日活跃数为0 daily_active = [0] * total_days for user in users: act_date = user['activated_on'] deact_date = user['deactivated_on'] # 计算用户活跃区间和当月的交集 active_start = max(act_date, month_start) active_end = min(deact_date, month_end + datetime.timedelta(days=1)) if deact_date else month_end + datetime.timedelta(days=1) if active_start >= active_end: continue # 转换为当月的日期索引 start_idx = (active_start - month_start).days end_idx = (active_end - month_start).days # 对应区间活跃数+1 for i in range(start_idx, end_idx): daily_active[i] += 1 # 输出每日数据 for idx, count in enumerate(daily_active): current_date = month_start + datetime.timedelta(days=idx) daily_cost = count * daily_per_cost total_monthly_cost += daily_cost print(f"{current_date.strftime('%Y-%m-%d')} {count} active users * ${daily_per_cost:.9f} = ${daily_cost:.9f} (subtotal: ${total_monthly_cost:.9f})") return total_monthly_cost
内容的提问来源于stack exchange,提问作者Ubun_2
相关产品推荐
相关产品推荐

