2009-06-05 9 views
1

私は大量のデータを持っていますが、通常は約2000+のエントリですが、このレポートでは私たちが望む限り見ることができるので、最大10,000レコードになる可能性があります大規模なリストをPythonの潜在的な条件で繰り返す

レポートは2つのカテゴリに分割され、各カテゴリ内では通貨で分割され、リスト内にいくつかのサブカテゴリがあります。

私の問題は、さまざまな小計を効率的に計算することにあります。私はDjangoを使用しており、それが適用される場合、通貨とカテゴリのtemplatetagを渡してからtemplatetagが合計をレンダリングします。場合によっては、通貨を渡さずに、カテゴリの小計だけがあることに注意してください。

そうのような通貨/カテゴリがあった場合、最初は、私はちょうど.filter()を使用して、各小計のための別々のクエリを使用していた:私はあまりにも多くのクエリを持っているでしょうとして

if currency: 
    entries = entries.filter(item_currency=currency) 

これが問題となりました、および生成時間(2,000+ミリ秒)の長すぎるので、私は単純なリストの内包表記とそれを介して、ループを右バット私のクエリを実行するために、リスト(エントリー)を使用することを選んだ、と:

totals['quantity'] = sum([e.quantity for e in entries]) 

マイあなたがまだそれを見ていない場合、問題があります..どのように私は効率的に条件を追加することができます各リストの理解の通貨/カテゴリのために?

totals['quantity'] = sum([e.quantity for e in entries if item_currency = currency]) 

を私が巨大な場合、ブロックを作ることができ、それは非常にきれいではないですし、メンテナンスの災害ですので、私は:時には彼らは時々彼らはので、私は単純に入力することができないだろう、そこではありません...洞察力のビットのためにStackOverflowのコミュニティに事前に感謝を差し伸べる:)

+0

1つの極小思想:Python 2.4以上をターゲットにしている限り、ジェネレータ表現の周りにリストは必要ありません。 sum(xのeのe)はsum(eのe in e)よりわずかに速く、意味的に同等でなければなりません。 – llimllib

+0

良いキャッチ!私はいくつかの点で私のコードを改訂しました。ありがとうございました:) – Bartek

答えて

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()は、囲みスコープ内のすべての変数にアクセスできるため、それ以上引数を渡す必要はありません。エントリを使用するすべてのロジックが1か所にあるという利点がありますが、リストの理解度を使用してsum()をより読みやすくすることはできますが、EntryMatches()では任意のロジックを使用できます。

+0

エレガントでシンプルなソリューション。そのことを考えることさえしなかった。ありがとう! – Bartek

関連する問題