Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

List comprehension conditionals for datetime objects

I am writing the following function that returns the last day of every month between two given dates:

import datetime as dt

def dates_list_last_day_of_month(start_date=(2000,1,1),end_date=(2023,4,26)):

    start_date = dt.date(*start_date)
    end_date = dt.date(*end_date)

    def last_day_of_month(year, month):
        next_month = dt.date(year, month, 1) + dt.timedelta(days=32)
        return next_month.replace(day=1) - dt.timedelta(days=1)
    
    last_days = []
    for year in range(start_date.year,end_date.year+1):
        for month in range(1,13):
            date = last_day_of_month(year,month)
            if start_date < date and date < end_date:
                last_days.append(date)
    return last_days

The above function works as intended and produces the correct list of dates. I, however, first tried to write this function using a list comprehension but couldn’t mangage to make it work. This was the code:

import datetime as dt

def dates_list_last_day_of_month(start_date=(2000,1,1),end_date=(2023,4,26)):

    start_date = dt.date(*start_date)
    end_date = dt.date(*end_date)

    def last_day_of_month(year, month):
        next_month = dt.date(year, month, 1) + dt.timedelta(days=32)
        return next_month.replace(day=1) - dt.timedelta(days=1)
    
    date = dt.date(1,1,1)
    last_days = [(date:=last_day_of_month(year,month)) for year in range(start_date.year,end_date.year+1) for month in range(1,13) if (start_date < date and date < end_date)]
    
    return last_days

As is, the output of the second function is an empty list. Trying with different combinantions of the condition in the comprehension and the initial declaration of ‘date’ yields different outputs, but none are the desired list. Some have dates ranging from the begining of the start date year, others include dates until the end of the end_date year.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How can the loops in the first code block be written as a list comprehension? Does the condition in the comprehension not work the same way it does in a for loop?

Thanks in advance!

>Solution :

Your assignment occurs after the condition so the value of date is still dt.date(1,1,1) when comparing (start_date < date and date < end_date).

Try writing you comprehension as a loop to better understand what’s going on. You should write it as follows:

last_days = [date for year in range(start_date.year,end_date.year+1) for month in range(1,13) if (start_date < (date:=last_day_of_month(year,month)) and date < end_date)]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading