2010-02-01 20 views
20

Me está resultando difícil encontrar una forma elegante de manejar este tipo de cosas. Tengo datos que regresan de una base de datos leída. Quiero ordenar en la fecha de envío. Sin embargo, la fecha de envío puede ser a veces nula. Actualmente estoy haciendo lo siguiente:En python, ordenando el campo de la fecha, el campo puede ser nulo en ocasiones

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

Pero, esto con bombas "TypeError: No se puede comparar a datetime.date NoneType" debido a algunos accoutingdates siendo nula.

¿Cuál es la forma "más correcta" o "más Pythonic" de manejar esto?

+0

¿Dónde cae 'None' en su género? ¿Primero? ¿Último? ¿En algún lugar en el medio? ¿Qué significa 'None' cuando se compara con una fecha? ¿Es "Ninguno" antes o después del 7 de diciembre de 2001? –

+0

Mi preferencia sería ordenar None como "antes" de todas las fechas válidas. – Wes

+0

Por cierto, puede ordenar su lista en su lugar: 'results = sorted (results, ...)' debería simplemente ser 'results.sort (...)' –

Respuesta

27

Utilizando una función key= está bien, sin duda, sólo hay que decidir cómo desea tratar los valores None - escoja un valor datetime que se quiere tratar como el equivalente de None con fines de clasificación. Ej .:

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

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

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

Sólo hay que ver cómo mucho más simple se trata de definir una función cmp lugar - y si lo hace un poco de la evaluación comparativa se encontrará que es también significativamente más rápido! No hay nada positivo en el uso de una función cmp en lugar de esta función key, y sería una mala opción de diseño hacerlo.

+0

Cambié mi respuesta aceptada a esta ... ¡muy hábil! ¡Gracias! – Wes

11

se puede utilizar una función de clasificación a medida que trata especialmente None:

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, ...) 

Este None trata de ser más pequeño que todos los objetos de fecha y hora.

Cuestiones relacionadas