简体   繁体   中英

Python: Comparing a date to a date within list of dictionaries

I have a (large) list of dictionaires, containing tasks and their metadata extracted from Wunderlist. The name of the list is tasktotal . These dictionaries within the list look like this:

{'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}

I would like to compare the 'due_date' value to the current date using datetime :

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

If the dictinary is due today or any day before today, I would like to return the 'title' value from this dictionary. I figured that the easiest way would be to create a new dictionary with all the entries that are due today, and then retrieve their 'title' values. So I made this search function:

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

However, when I run this search on my tasktotal list, I get nothing returned.

print(search(tasktotal))

[]
Process finished with exit code 0

I don't understand what I am doing wrong here? Or is there maybe another more efficient way of retrieving the values that I need?

EDIT 1:

When I try the solution by @Peter, I get this error:

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

EDIT 2: When I switch my brackets, like @James K and @RichSmith suggested, I get this error

    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

The bracketing is wrong for

element[datetime.strptime('due_date')]

This tries to convert the string "due_date" to a time, and then look up that in the dictionary. Instead you need to lookup the date, then convert it.

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

If you want a list of titles returned, you can just use element['title'] .

I've not really used datetime so quickly threw together a slightly different solution, it converts the date to its timestamp so you can adjust the format if needed. To me at least, since it's comparing the numbers themselves instead of relying on datetime to do the comparison, it seems a bit more robust.

I did a quick test and this is roughly 20-25% slower, it takes 1.25 seconds per 6k values as opposed to 1 though, so it's not too noticeable.

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]

For the record, the 86400 which pops up is just to get the current time in seconds rounded to the start of the day, since that's the highest accuracy the data uses.

I think you need to move your strptime.

try:

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

that way the element["due_date"] will fetch the date in each of your dictionaries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM