2010-02-01 13 views
20

Ich habe eine harte Zeit mit einem glatten Weg zu kommen, mit dieser Art zu kommen. Ich habe Daten, die von einer gelesenen Datenbank zurückkommen. Ich möchte nach dem Accoutingdatum suchen. Allerdings kann accoutingdate manchmal null sein. Ich mache zur Zeit folgendes:In Python, sortieren nach Datum Feld, Feld kann manchmal Null

results = sorted(results, key=operator.itemgetter('accountingdate'), reverse=True) 

Aber diese Bomben mit: aufgrund einiger accoutingdates ist null „Typeerror nicht datetime.date zu NoneType vergleichen“.

Was ist der "richtigste" oder "pythonischste" Weg, damit umzugehen?

+0

Wo fällt 'None'? Zuerst? Letzte? Irgendwo in der Mitte? Was bedeutet 'None' im Vergleich zu einem Date? Ist 'None' vor oder nach dem 7. Dezember 2001? –

+0

Meine Präferenz wäre, None als "vor" allen gültigen Daten zu sortieren. – Wes

+0

Btw, können Sie Ihre Liste an Ort und Stelle sortieren: 'Ergebnisse = sortiert (Ergebnisse, ...)' sollte einfach 'results.sort (...)' –

Antwort

27

Mit einer key= Funktion ist auf jeden Fall richtig, Sie müssen nur entscheiden, wie Sie die None Werte behandeln wollen - wählen Sie einen datetime Wert, den Sie als Äquivalent None zu Sortierzwecken behandeln möchten. Z.B .:

import datetime 
mindate = datetime.date(datetime.MINYEAR, 1, 1) 

def getaccountingdate(x): 
    return x['accountingdate'] or mindate 

results = sorted(results, key=getaccountingdate, reverse=True) 

nur sehen, wie viel einfacher diese stattdessen eine cmp Funktion als definieren ist - und wenn Sie einige Benchmarking tun werden Sie es auch deutlich schneller finden! Es gibt überhaupt keinen Vorteil bei der Verwendung einer cmp Funktion anstelle dieser key Funktion, und es wäre eine schlechte Design-Wahl, dies zu tun.

+0

Ich habe meine angenommene Antwort auf diese geändert ... sehr glatt! Vielen Dank! – Wes

11

Sie können eine benutzerdefinierte Sortierfunktion verwenden, die None speziell behandelt:

def nonecmp(a, b): 
    if a is None and b is None: 
    return 0 
    if a is None: 
    return -1 
    if b is None: 
    return 1 
    return cmp(a, b) 

results = sorted(results, cmp=nonecmp, ...) 

Diese behandelt None als kleiner ist als alle Datetime-Objekte.