I have an list:
a=[datetime.date(2010,10,20),1,4,datetime.date(2013,10,20)]
As you can see the list contains different types of elements. How can I get the max date within the list?
My attempt:
from datetime import datetime
b=datetime.max(a)
print b
For guidence Find oldest/youngest datetime object in a list
from datetime import datetime
datetime_list = [
datetime(2009, 10, 12, 10, 10),
datetime(2010, 10, 12, 10, 10),
datetime(2010, 10, 12, 10, 10),
datetime(2015, 2, 12, 10, 10), # future
datetime(2016, 2, 12, 10, 10), # future
]
oldest = min(datetime_list)
youngest = max(datetime_list)
The prior post has filter to exclude future events
First, keeping dates and integers together in the same list -- except as an intermediate step -- can be a sign your data structure isn't appropriate. That said, you can easily take the max only of the dates by using a generator expression:
>>> import datetime
>>> a=[datetime.date(2010,10,20),1,4,datetime.date(2013,10,20)]
>>> max(d for d in a if isinstance(d, datetime.date))
datetime.date(2013, 10, 20)
Related
I am trying to write a simple function to compare a list of dates to today in order to find dates that are more than 13 years old. For the first part of the challenge I’m just trying to write the function that will compare the dates to find the difference today and each in the birthdays list.
import datetime
birthdays = [
datetime.datetime(2012, 4, 29),
datetime.datetime(2006, 8, 9),
datetime.datetime(1978, 5, 16),
datetime.datetime(1981, 8, 15),
datetime.datetime(2001, 7, 4),
datetime.datetime(1999, 12, 30)
]
today = datetime.datetime.today()
def is_over_13(dt):
Diff = (today - dt)
Return (diff)
Is_over_13(birthdays)
The problem I seem to be facing is that I’m trying to compare a datetime object to a list. So my thinking is that I need to be able to do something to the list to make it compatible to compare? Or the other way round.
I’m learning Python and this is step 1 of a specific code challenge so I can’t use lambda or panda or libraries. I’m expected to do it using functional chaining or comprehensions.
Thanks in advance
I think you need a loop.
for dt in birthdays:
diff=(today-dt)
return diff
You can loop over a list of datetimes to all compare them one by one with today.
This function will return True if one date is over 13 years.
def is_it_over_13(birthday_list):
for date in birthday_list:
if abs(today - date) > datetime.timedelta(days = 13*365):
return True
else:
return False
import datetime
birthdays = [
datetime.datetime(2012, 4, 29),
datetime.datetime(2006, 8, 9),
datetime.datetime(1978, 5, 16),
datetime.datetime(1981, 8, 15),
datetime.datetime(2001, 7, 4),
datetime.datetime(1999, 12, 30)
]
def is_over_13(dt):
today = datetime.datetime.today()
diff = (datetime.datetime.now() - dt).days
# 4745 == 13*365
if diff>4745:
return dt
for i in birthdays:
print(is_over_13(i))
You have a few tweaks to makes.
import datetime
birthdays = [
datetime.datetime(2012, 4, 29),
datetime.datetime(2006, 8, 9),
datetime.datetime(1978, 5, 16),
datetime.datetime(1981, 8, 15),
datetime.datetime(2001, 7, 4),
datetime.datetime(1999, 12, 30)
]
today = datetime.datetime.today()
def is_over_13(dt):
diff = (today - dt) # you have capital D, need to match variable name with lower case.
return diff # Return should be return
for birthday in birthdays: # loop over each day to check
print(is_over_13(birthday)) ## you have capital I, needs to match your function name with lower case i
Also your function name says is_over_13 which implies true or false return i think. You might want to take the diff value and compare it to 13 years and return true or false
This might look like
import datetime
birthdays = [
datetime.datetime(2012, 4, 29),
datetime.datetime(2006, 8, 9),
datetime.datetime(1978, 5, 16),
datetime.datetime(1981, 8, 15),
datetime.datetime(2001, 7, 4),
datetime.datetime(1999, 12, 30)
]
today = datetime.datetime.today()
DAYS_IN_YEAR = 365
YEARS = 13
def is_over_13(dt):
diff = (today - dt).days # get the days for your diff
return diff > (DAYS_IN_YEAR * YEARS) # return if greater than 13 or not
for birthday in birthdays:
print(is_over_13(birthday))
This will get you started. You need a loop. In this case, I used a comprehension:
import datetime
birthdays = [
datetime.datetime(2012, 4, 29),
datetime.datetime(2006, 8, 9),
datetime.datetime(1978, 5, 16),
datetime.datetime(1981, 8, 15),
datetime.datetime(2001, 7, 4),
datetime.datetime(1999, 12, 30)
]
today = datetime.datetime.today()
>>> [f'{today.date()} - {bd.date()}>13: {((today-bd).days)>365.2425*13}' for bd in birthdays]
['2022-01-05 - 2012-04-29>13: False', '2022-01-05 - 2006-08-09>13: True', '2022-01-05 - 1978-05-16>13: True', '2022-01-05 - 1981-08-15>13: True', '2022-01-05 - 2001-07-04>13: True', '2022-01-05 - 1999-12-30>13: True']
Because of leap years, time differences are expressed in days, minutes, seconds. This uses a common, but less than perfect, shortcut of estimating a year difference by multiplying a day difference by 365.2425 that is usually accurate but not 100%.
To get 100% accuracy, you need to detect leap year birthdays and adjust the date to 2/28/the_year in a non-leap year.
To do that, use this function:
def is_older_than(bd, age, day=datetime.datetime.today()):
try:
age_date=bd.replace(year=bd.year+age)
except ValueError:
age_date=bd.replace(year=bd.year+age, day=28)
return age_date<=day
Then redo the loop that will be accurate by the day no matter what:
>>> [f'{today.date()} - {bd.date()}>13: {is_older_than(bd, 13)}' for bd in birthdays]
['2022-01-05 - 2012-04-29>13: False', '2022-01-05 - 2006-08-09>13: True', '2022-01-05 - 1978-05-16>13: True', '2022-01-05 - 1981-08-15>13: True', '2022-01-05 - 2001-07-04>13: True', '2022-01-05 - 1999-12-30>13: True']
I have a dictionary weeks that is populated using a for loop. The dictionary contains arguments passed to a function. I'd like to update the code to read second argument and pass that to the function.
from datetime import date, datetime, timedelta
weeks = {}
def generate(date):
# generate 8 rows with 4 cells each
for d in range(1, 32, 4):
start = (date + timedelta(days=d)).strftime('%Y-%m-%d')
week = pd.date_range(start, periods=4).to_pydatetime().tolist()
weeks[d] = week
print(weeks)
def create(arg1):
# do something
return ...
This function populates a dictionary with dates as a list of values.
{1: [datetime.datetime(2021, 10, 13, 0, 0), datetime.datetime(2021, 10, 14, 0, 0), datetime.datetime(2021, 10, 15, 0, 0), datetime.datetime(2021, 10, 16, 0, 0)], 5: [datetime.datetime(2021, 10, 17, 0, 0), datetime.datetime(2021, 10, 18, 0, 0), datetime.datetime(2021, 10, 19, 0, 0), datetime.datetime(2021, 10, 20, 0, 0)],.......
Now I'd like to either modify the weeks dictionary or create a new dictionary that I'll iterate over to read the second argument of the function.
The function call:
[create(i)] for i in weeks[1]
I'd like to modify this call to include a second argument which is read from the dictionary with same structure as well. Pseudocode below:
[create(i,j)] for i,j in weeks[1], value[1]
where value is the new dictionary with populate, if we don't modify the existing dict weeks. I'd appreciate advise on which approach makes sense and how can I modify the function call to pass two arguments.
value dict will look like this:
value = {1: [1000, 1200, 1400, 1600], 5: [2000, 2200, 2400, 2600]}
Use zip to iterate over two lists in parallel, it will yield pairs in tuples
[create(i, j) for i, j in zip(weeks[1], value[1]))
I want to filter my list of time string elements with the help of python datetime library.
I have a array like -
time_Arr = ["0:0:16","3:59:9","2:50:32","23:46:52","20:30:12"]
I want to make it be filtered from the ascending order (0:0:0 - 23:59:59) accordingly.
Also i will have bulk of data (array should be almost containing more than 5k ) so what will be most efficient for this?
How can i achieve this in python?
the resulting array should be something like -
["0:0:16","2:50:32","3:59:9","20:30:12","23:46:52"]
This will convert the strings to datetime, sort them then output a list with your desired format.
from datetime import datetime
time_Arr = ["0:0:16","3:59:9","2:50:32","23:46:52","20:30:12"]
sorted(time_Arr, key=lambda x: datetime.strptime(x, '%H:%M:%S'))
['0:0:16', '2:50:32', '3:59:9', '20:30:12', '23:46:52']
Use datetime to parse the time then sort:
from datetime import datetime
time_Arr = ["0:0:16","3:59:9","2:50:32","23:46:52","20:30:12"]
time_Arr = sorted([datetime.strptime(t, "%H:%M:%S") for t in time_Arr])
# [datetime.datetime(1900, 1, 1, 0, 0, 16),
# datetime.datetime(1900, 1, 1, 2, 50, 32),
# datetime.datetime(1900, 1, 1, 3, 59, 9),
# datetime.datetime(1900, 1, 1, 20, 30, 12),
# datetime.datetime(1900, 1, 1, 23, 46, 52)]
from datetime import datetime
sorted([datetime.strptime(time, "%H:%M:%S") for time in time_Arr])
I want to create a parse function with lambda able to recognize two different formats
"2014-01-06 15:23:00"
and
"2014-01-06"
The idea is to use this function to create a pandas dataframe but in some of the values the hour is missing
This is my first idea
parse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S') if x is True else pd.datetime.strptime(x, '%Y-%m-%d')
it seems that x is True is not correct
Any idea??
dateutil has a parser that handles multiple formats:
>>> dateutil.parser.parse('2015-07-04')
datetime.datetime(2015, 7, 4, 0, 0)
>>> dateutil.parser.parse('2015-07-04 11:23:00')
datetime.datetime(2015, 7, 4, 11, 23)
>>> dateutil.parser.parse('2015-07-04T11:23:56')
datetime.datetime(2015, 7, 4, 11, 23, 56)
Even non iso formats like this
>>> dateutil.parser.parse('5-6-15')
datetime.datetime(2015, 5, 6, 0, 0)
I have some strings which come to me in formats like
29-Jul-2014 or 03-Aug-2015
What is the easiest way to convert this to a datetime.date object?
I can only think to make a dictionary like d = {'Jul': 7, 'Aug': 8, ...} and then do
dt = datetime.date(year, d[month], day)
Is there any other easier way and avoid the creation of this dictionary?
Thanks
Use datetime.datetime.strptime to convert the string to datetime.datetime object.
>>> datetime.datetime.strptime('29-Jul-2014', '%d-%b-%Y')
datetime.datetime(2014, 7, 29, 0, 0)
Then, use datetime.datetime.date method to convert it to datetime.date object:
>>> datetime.datetime.strptime('29-Jul-2014', '%d-%b-%Y').date()
datetime.date(2014, 7, 29)
The easy way is use dateutil.parse module, it lets to parse the common date formats, even if you don't know what it is using currently
Ex:
>>> import dateutil.parser
>>>
>>> utc_time = '2014-07-29T00:00:00'
>>> verbose_time = '29-Jul-2014'
>>> some_locale = '29/7/14'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 7, 29, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 7, 29, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 7, 29, 0, 0)
Once you have a datetime object, you only should invoke the datetime.date() method