在Python中遍历可能包含条件的大型列表
我有一大堆数据,通常大约有2000条记录,但在这个报告中,我们可以查看更多数据,最多可以达到10000条。
这个报告分成两大类,然后在每个类别下,我们再按货币进行细分,所以在列表中会有几个子类别。
我遇到的问题是如何高效地计算各种小计。我使用的是Django,并且传递一个模板标签,包含货币和类别(如果适用),然后这个模板标签会渲染出总数。需要注意的是,有时候我只需要一个类别的小计,而不传递货币。
最开始,我是为每个小计使用单独的查询,只要有货币或类别,就用.filter()来查询,像这样:
if currency:
entries = entries.filter(item_currency=currency)
但这样的问题是查询太多,生成时间太长(超过2000毫秒),所以我决定直接用list(entries)来执行查询,然后用简单的列表推导式来遍历它:
totals['quantity'] = sum([e.quantity for e in entries])
如果你还没发现我的问题,那就是……我该如何在每个列表推导式中高效地添加货币/类别的条件?有时候这些条件不存在,有时候又存在,所以我不能简单地写:
totals['quantity'] = sum([e.quantity for e in entries if item_currency = currency])
我可以写一个很大的if块,但那样不太整洁,而且维护起来会很麻烦,所以我想向Stackoverflow社区寻求一些建议……提前谢谢大家 :)
1 个回答
6
你可以定义一个小的内联函数:
def EntryMatches(e):
if use_currency and not (e.currency == currency):
return False
if use_category and not (e.category == category):
return False
return True
然后
totals['quantity'] = sum([e.quantity for e in entries if EntryMatches(e)])
这样一来,EntryMatches() 就可以访问到它外面所有的变量,所以不需要再传入其他参数。这样做的好处是,决定使用哪些条目的所有逻辑都集中在一个地方,你仍然可以使用列表推导式来让 sum() 更易读,但现在你可以在 EntryMatches() 中使用任意的逻辑。