如何用纯Python统计字典列表中符合筛选条件的记录数
纯Python实现字典列表的条件计数
需要统计Python字典列表中符合筛选条件的记录出现次数,生成包含年份、国家和对应计数的结果结构。此前了解过Django模型中的实现方式,现需用纯Python完成该计数逻辑(仅计数,不求和)。
示例数据
dataset =[ { 'Country': 'GB', 'Pollutant': 'SO2', 'Pollution': 10, 'Year': 2016 }, { 'Country': 'AL', 'Pollutant': 'O3', 'Pollution': 10, 'Year': 2015 }, { 'Country': 'BE', 'Pollutant': 'SO2', 'Pollution': 5, 'Year': 2016 }, { 'Country': 'GB', 'Pollutant': 'SO2', 'Pollution': 10, 'Year': 2016 }, { 'Country': 'BE', 'Pollutant': 'SO2', 'Pollution': 10, 'Year': 2016 }, ]
原尝试代码(含Django语法)
原代码使用了Django专属的Q对象和filter方法,无法在纯Python环境运行,需替换为原生逻辑:
all_Years = sorted(set([v['Year'] for v in dataset])) all_countries = sorted(set([v['Country'] for v in dataset])) print(all_Years) print(all_countries) for country in all_countries: new_data = { 'years': all_Years, 'country': country, 'data' : [] } for year in all_Years: # Django风格的筛选,纯Python不支持 # f = Q(year = year, country=country) # country_count = dataset.filter(f).count() new_data['data'].append(country_count if country_count else 0)
期望输出
[ {'years': [2015,2016], 'country': 'AL', 'data': [1, 0]}, {'years': [2015,2016], 'country': 'BE', 'data': [0, 2]}, {'years': [2015,2016], 'country': 'GB', 'data': [0, 2]} ]
注:原期望输出中BE的data为[1,2],但根据示例数据,BE无2015年记录,正确计数应为[0,2]
纯Python解决方案
基础实现(直观易懂)
遍历每个国家和年份,用生成器表达式统计符合条件的记录数:
all_Years = sorted(set(v['Year'] for v in dataset)) all_countries = sorted(set(v['Country'] for v in dataset)) result = [] for country in all_countries: new_data = { 'years': all_Years, 'country': country, 'data': [] } for year in all_Years: # 统计符合国家和年份的记录数 count = sum(1 for item in dataset if item['Country'] == country and item['Year'] == year) new_data['data'].append(count) result.append(new_data) print(result)
优化实现(高效处理大数据集)
先预处理统计所有(国家,年份)组合的计数,避免重复遍历数据集:
from collections import defaultdict # 预处理:一次遍历完成所有组合的计数 count_map = defaultdict(int) for item in dataset: key = (item['Country'], item['Year']) count_map[key] += 1 all_Years = sorted(set(v['Year'] for v in dataset)) all_countries = sorted(set(v['Country'] for v in dataset)) result = [] for country in all_countries: new_data = { 'years': all_Years, 'country': country, # 直接从预处理的字典中获取计数,无则返回0 'data': [count_map.get((country, year), 0) for year in all_Years] } result.append(new_data) print(result)
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

