This might be somehow of a trivial question, but I have a dictionary on which I would like to apply some 10 functions to modify its content.
I think this would be a good case for reduce
but I cannot seem to make it work.
Here's an example
from datetime import datetime
import re
from functools import reduce
d_ = {
"dob_partial": "20120314",
"service_address_country":"Uni44ed Kind-om"
}
What I would like as a results:
d_ = {
"dob_partial": "20120314",
"dob": datetime.datetime(2012, 3, 14, 0, 0)
"service_address_country":"Uni44ed Kind-om"
"service_address_country_clean":"Unied Kindom"
}
Here's the replicable code:
# pre-processing functions
def clean_address_country_code(d):
key = 'service_address_country'
d[key + 'clean'] = re.sub('[^a-zA-Z ]+', '', d[key])
return d
def add_datestr_to_date(d):
key = 'dob_partial'
d['dob'] = datetime.strptime(d.get(key), '%Y%m%d')
return d
# pipeline function to apply all preprocessing functions
def apply_all_preprocessing(fns, dic):
reduce(lambda fn, d=dic: fn(dic), fns)
return dic
fns = [add_datestr_to_date, clean_address_country_code]
apply_all_preprocessing(fns, d_)
Which works only partially (it applies only the first function in the list fns
):
>>> print(apply_all_preprocessing(fns, d_))
{'dob_partial': '20120314', 'service_address_country': 'Uni44ed K-?indom', 'dob': datetime.datetime(2012, 3, 14, 0, 0)}
The order of your lambda arguments are swapped. It should be lambda value, element: ...
. In your case:
def apply_all_preprocessing(fns, dic):
return reduce(lambda d,f: f(d), fns, dic)
Supply the initial dictionary as the last argument to reduce()
.