2009-06-05 12 views
1

Ich habe große Datenblöcke, normalerweise bei etwa 2000+ Einträge, aber in diesem Bericht haben wir die Möglichkeit, so weit wie wir wollen, so könnte es bis zu 10.000 Datensätze seinIterieren durch große Listen mit möglichen Bedingungen in Python

Der Bericht ist unterteilt in: Zwei Kategorien und dann innerhalb jeder Kategorie, wir teilen sie nach Währung, so dass wir mehrere Unterkategorien innerhalb der Liste haben.

Mein Problem kommt in der effizienten Berechnung der verschiedenen Zwischensummen. Ich verwende Django und übergebe ein TemplateTag die Währung und die Kategorie, wenn es zutrifft, und dann gibt der TemplateTag die Summe aus. Beachten Sie, dass ich manchmal eine Zwischensumme nur für die Kategorie ohne Währung habe.

Anfang war ich eine separate Abfrage für jeden Wert Ihrer Verwendung von nur mit .filter(), wenn es eine Währung/Kategorie wie so war:

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

Dies wurde zu einem Problem, da ich viele Fragen hat, würde auch und zu lange eine Generationszeit (2.000 + ms), so entschied ich mich Liste (Einträge) zu verwenden, um meine Abfrage rechts von der Fledermaus auszuführen, und dann der Schleife durch sie mit einfachen Listenkomprehensionen:

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

Mein Problem, wenn Sie es noch nicht sehen, liegt in .. Wie kann ich die Bedingung effizient hinzufügen für Währung/Kategorie auf jedem Listenverständnis? Manchmal werden sie nicht da sein, manchmal werden sie, so kann ich nicht geben Sie einfach ein:

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

Ich konnte eine große machen, wenn Block, aber das ist nicht sehr sauber und ist ein Wartungs-Katastrophe, also bin ich für ein wenig Einblick in die Gemeinschaft Stackoverflow Annäherung .. Vielen dank im Voraus :)

+0

ein super-kleiner Gedanke: Solange Sie Python 2.4 oder höher als Ziel haben, brauchen Sie nicht die Liste um Ihren Generator Ausdruck. sum (e für e in x) sollte etwas schneller sein als sum ([e für e in x]) und semantisch äquivalent. – llimllib

+0

Guter Fang! Ich habe meinen Code in einigen Punkten in Bezug auf das überarbeitet, danke :) – Bartek

Antwort

6

Sie könnten eine kleine Inline-Funktion definieren:

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 

dann

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

EntryMatches() hat Zugriff auf alle Variablen im umschließenden Bereich, sodass keine weiteren Argumente übergeben werden müssen. Sie erhalten den Vorteil, dass die gesamte Logik, für die Einträge verwendet werden, an einem Ort ist. Sie können trotzdem das Listenverständnis verwenden, um die sum() lesbarer zu machen, aber Sie können jetzt in EntryMatches() beliebige Logik haben.

+0

Elegante und einfache Lösung. Hab nicht mal daran gedacht. Vielen Dank! – Bartek

Verwandte Themen