2016-11-03 5 views
1

У меня есть (большой) список словарей, содержащих задачи и их метаданные, извлеченные из Wunderlist. Название списка: tasktotal. Эти словари в списке выглядеть следующим образом:Python: сравнение даты с датой в списке словарей

{'due_date': '2016-11-30', 'created_by_request_id': 'RqID:RqIDKey', 'type': 'task', 'title': 'This is a task ', 'completed': False, 'id': MYID, 'created_by_id': MYID, 'created_at': '2016-10-14T11:11:52.916Z', 'revision': 2, 'starred': False, 'list_id': MYLISTID} 

Я хотел бы сравнить «due_date» значение текущей даты с помощью datetime:

date_today = datetime.datetime.now().date() 

Если dictinary связано сегодня или в любой день до того сегодня я хотел бы вернуть значение «title» из этого словаря. Я полагал, что самым простым способом было бы создать новый словарь со всеми записями, которые должны появиться сегодня, а затем получить их значения «title». Так что я сделал эту функцию поиска:

def search(i): 
    return [element for element in i if element[datetime.strptime('due_date')] >= date_today] 

Однако, когда я запускаю этот поиск на моем tasktotal список, я получаю ничего не вернулось.

print(search(tasktotal)) 

[] 
Process finished with exit code 0 

Я не понимаю, что я здесь делаю неправильно? Или может быть еще один более эффективный способ получить нужные мне ценности?

EDIT 1:

При попытке решения по @Peter, я получаю эту ошибку:

return [element['title'] for element in i if date_convert(element['due_date']) >= current_time] 
    KeyError: 'due_date 

EDIT 2: Когда я включаю мои скобки, как @James K и @RichSmith предложил, я получаю эту ошибку

return [element for element in i if datetime.strptime(element['due_date'], "%Y-%m-%d") >= date_today] 
TypeError: can't compare datetime.datetime to datetime.date 
+0

Возможно, вы захотите ответить на каждый ответ конкретными сообщениями для ответа. –

+0

Извините, совершенно новый здесь, спасибо за подсказку! –

ответ

0

Думаю, вам нужно переместить y наша страсть.

попробовать:

def search(i): 
    return [element for element in i if datetime.strptime(element["due_date"]) >= date_today] 

этак element["due_date"] будет получать дату в каждой из ваших словарей.

+0

Вы забыли один из аргументов –

1

Экспобрекетинг неправильно для

element[datetime.strptime('due_date')] 

Это пытается преобразовать строку «due_date» в то время, а затем посмотреть, что в словаре. Вместо этого вам нужно найти дату, а затем преобразовать ее.

datetime.strptime(element['due_date'], "%Y-%m-%d").date() 
+0

Конечно! Но все же, та же ошибка, что и #Peter: return [элемент для элемента в i, если datetime.strptime (элемент ['due_date'], "% Y-% m-% d")> = date_today] TypeError: can not сравните datetime.datetime с datetime.date –

+1

Ответ забыли один из аргументов, но вы это исправили. Чтобы исправить тип, обратите внимание, что datetime.strptime возвращает дату-время, которое вы не можете напрямую сравнить с датой. Но вы можете преобразовать его в дату сначала, позвонив .date() –

+0

Включенный в ответ. –

1

Если вы хотите, список названий вернулся, вы можете просто использовать element['title'].

Я действительно не использовал datetime так быстро, что бросил немного другое решение, оно преобразует дату в метку времени, чтобы при необходимости можно было отрегулировать формат. Для меня, по крайней мере, потому что он сравнивает числа, а не полагается на datetime, чтобы сделать сравнение, кажется немного более надежным.

Я сделал быстрый тест, и это примерно на 20-25% медленнее, он занимает 1,25 секунды на 6 килобайт, а не 1, так что это не слишком заметно.

import datetime 
import time 

def date_convert(due_date): 
    return time.mktime(datetime.datetime.strptime(due_date, "%Y-%m-%d").timetuple()) 

def search(i): 
    current_time = 86400 * int(time.time()/86400) 
    future_date = '3000-01-01' 
    return [element['title'] for element in i if date_convert(element.get('due_date', future_date)) <= current_time] 

Для записи, 86400 который всплывает только, чтобы получить текущее время в секундах, округленное до начала рабочего дня, так как это самая высокая точность данных использует.

+0

Мне это нравится! Но теперь у меня другая ошибка: return [element ['title'] для элемента в i, если date_convert (element ['due_date'])> = current_time] KeyError: 'due_date –

+0

@kenny Ostrom Это может быть так, словари извлекаются из учетной записи Wunderlist. Не всякая задача здесь имеет сроки, поэтому не каждый словарь имеет элемент «due_date». Это проблема с этим подходом? –

+0

Это работает для данных, которые вы дали, но не в ваших реальных данных, потому что ваши реальные данные разные. Я предлагаю, чтобы вместо элемента ['due_date'] вы использовали element.get ('due_date', default). Или вы можете просто игнорировать неудачные записи, проверяя, является ли «due_date» в элементе и ... - извините, что я удалил свой комментарий, чтобы переписать лучший. –

Смежные вопросы