I have the following code which removes a dict
from a list
of dict
s in Python based on whether the Date
key has a value greater than 180 days ago (ideally needs to be 6 months):
gp_clinicals_meds_repeat = session["gp_clinicals_meds_repeat"]
for i in range(len(gp_clinicals_meds_repeat["GpRepeatMedicationsList"])):
date_object = parser.parse(gp_clinicals_meds_repeat["GpRepeatMedicationsList"][i]["Date"])
months_between = datetime.now() - date_object
if months_between.days > 180:
del gp_clinicals_meds_repeat["GpRepeatMedicationsList"][i]
An example of my JSON is below (just has one entry but could have hundreds):
{
"GpRepeatMedicationsList": [{
"Constituent": "",
"Date": "2021-07-15T00:00:00",
"Dosage": "0.6ml To Be Taken Each Day",
"LastIssuedDate": "2021-07-15T00:00:00",
"MixtureId": "",
"Quantity": "50",
"ReadCode": "DADR8795BRIDL",
"Rubric": "Dalivit oral drops (Dendron Brands Ltd)",
"TenancyDescription": "Orglinks",
"Units": "ml"
}],
"TotalItemCount": 1
}
I was thinking list comprehension but not sure how to parse the string as a date within it.
My code does not work correctly if it needs to remove two elements in a row, since it will always increment i
, regardless of whether it just removed the element at index i
. Also, it will keep running until the end of the original length, so if you remove any elements, this code will end with an exception because gp_clinicals_meds_repeat["GpRepeatMedicationsList"][i]
will no longer exist for the later values of i
.
Any suggestions?
CodePudding user response:
You can use a list comprehension with an if
to easily do this. I separated the criteria in a function since it may be a bit more complicated. I also recommend using pandas.Timestamp
to handle dates, as it is very robust:
import pandas as pd
def is_recent(entry):
date_object = pd.to_datetime(entry["Date"])
days_between = pd.Timestamp.today() - date_object
return days_between < pd.Timedelta(days=180)
original_clinicals = gp_clinicals_meds_repeat["GpRepeatMedicationsList"]
recent_clinicals = [entry for entry in original_clinicals if is_recent(entry)]
gp_clinicals_meds_repeat["GpRepeatMedicationsList"] = recent_clinicals # Replace the original list
To get 6 months instead of 180 days, you can use dateutil.relativedelta
s. The is_recent
function can be changed like (you could add a parameter to allow a configurable number of months).
import pandas as pd
import dateutil.relativedelta as relativedelta
def is_recent(entry):
limit_time = pd.Timestamp.today() - relativedelta.relativedelta(months=6)
return pd.to_datetime(entry["Date"]) > limit_time
original_clinicals = gp_clinicals_meds_repeat["GpRepeatMedicationsList"]
recent_clinicals = [entry for entry in original_clinicals if is_recent(entry)]