在Python中遍历可能包含条件的大型列表

1 投票
1 回答
692 浏览
提问于 2025-04-15 12:03

我有一大堆数据,通常大约有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() 中使用任意的逻辑。

撰写回答