Concatinating nested dictionary values based on regular expressions

Viewed 31

I have a nested dictionary that contains dates and their corresponding object types (not objects as thought of as in programing) that looks like this:

dict1 = {0: {'date': ['01', 'MAY', '14', '11MAY', '14', '18', 'MAY', '14'],
             'objecttype': ['Table', 'Anything', 'Chair']},
         1: {'date': ['12', 'MAY', '14', '12MAY14', '15MAY', '14'],
             'objecttype': ['Cup', 'Chair', 'fan']},
         2: {'date': ['05', 'MAY', '14', '13MAY14', '16MAY', '14'],
             'objecttype': ['Home', 'Desk', 'Pencil']},
         3: {'date': ['14', 'MAY', '14', '14MAY', '14', '04MAY14'],
             'objecttype': ['Cup', 'Stationery', 'Book']},
         4: {'date': ['15', 'MAY', '14', '15MAY14', '01', 'MAY', '14'],
             'objecttype': ['Eraser', 'Pen', 'Notebook']}}

All of the dates and objects have uniques keys like 0-4.

As can be seen most of the dates are not in a proper format and for us a proper format is [Day][Month][Year], looks like this:

04MAY14

My approach to solving this problem is with regular expressions and looping through dates twice. in the first go I want to look for all date values where I find only two digits like this for example '04' and concatenate them to the next value in list if it contains only three alphabets like this 'MAY' . After this step, most of the date values in the dict will look like this [Day][Month] .

04MAY

In the next loop I want to find all instances of date where we have day and month only and concatenate them to the next value in the list which should be a year value having two digits so that we have all dates in this format eventually:

04MAY14

The final dict will look like this:

dict1 = {0: {'date': ['01MAY14', '11MAY14', '18MAY14'],
             'objecttype': ['Table', 'Anything', 'Chair']},
         1: {'date': ['12MAY14', '12MAY14', '15MAY14'],
             'objecttype': ['Cup', 'Chair', 'fan']},
         2: {'date': ['05MAY14', '13MAY14', '16MAY14'],
             'objecttype': ['Home', 'Desk', 'Pencil']},
         3: {'date': ['14MAY14', '14MAY14', '04MAY14'],
             'objecttype': ['Cup', 'Stationery', 'Book']},
         4: {'date': ['15MAY14', '15MAY14', '01MAY14'],
             'objecttype': ['Eraser', 'Pen', 'Notebook']}}

I'm having trouble implementing this in python, would appreciate it if someone can help me out. Thanks

2 Answers

You can use datetime instead of regex:

from datetime import datetime

datetime_object = datetime.strptime('01MAY14', '%d%b%y')
print(datetime_object.strftime('%d/%m/%Y'))
#01/05/2014

Longer answer:

def get_date(d):
    if len(d) == 7:
        return datetime.strptime(d, '%d%b%y')
    else:
        return datetime.strptime(d, '%d%b')

def get_year(l):
    years = list()
    for d in l:
        y = get_date(d).year
        if y and (y not in years) and (y != 1900):
            years += [get_date(d).year]
    return next(iter(years))

def get_date_with_year(d, y):
    if len(d) == 7:
        return datetime.strptime(d, '%d%b%y')
    else:
        return datetime.strptime(d+str(y), '%d%b%Y')

def get_fixed_dates(l):

    year = get_year(l)
    return [get_date_with_year(d, year) for d in l]

l = '9MAY', '12MAY', '15MAY14'
print(get_fixed_dates(l))
#[datetime.datetime(2014, 5, 9, 0, 0), datetime.datetime(2014, 5, 12, 0, 0), datetime.datetime(2014, 5, 15, 0, 0)]

To apply to all dicts:

def helper(dic):
    dic['date'] = get_fixed_dates(dic['date'])
    return dic
    

new_dict = {k: helper(v) for k, v in dict.items()}

You can first separate the digit values from the month in text, and then regroup:

import re
def to_dates(d):
   r = [i for a in d for i in re.findall('\d+|[a-zA-Z]+', a)]
   return [''.join(r[i:i+3]) for i in range(0, len(r), 3)]

dict1 = {0: {'date': ['01', 'MAY', '14', '11MAY', '14', '18', 'MAY', '14'], 'objecttype': ['Table', 'Anything', 'Chair']}, 1: {'date': ['12', 'MAY', '14', '12MAY14', '15MAY', '14'], 'objecttype': ['Cup', 'Chair', 'fan']}, 2: {'date': ['05', 'MAY', '14', '13MAY14', '16MAY', '14'], 'objecttype': ['Home', 'Desk', 'Pencil']}, 3: {'date': ['14', 'MAY', '14', '14MAY', '14', '04MAY14'], 'objecttype': ['Cup', 'Stationery', 'Book']}, 4: {'date': ['15', 'MAY', '14', '15MAY14', '01', 'MAY', '14'], 'objecttype': ['Eraser', 'Pen', 'Notebook']}}
new_dict = {a:{**b, 'date':to_dates(b['date'])} for a, b in dict1.items()}

Output:

{0: {'date': ['01MAY14', '11MAY14', '18MAY14'], 'objecttype': ['Table', 'Anything', 'Chair']}, 
 1: {'date': ['12MAY14', '12MAY14', '15MAY14'], 'objecttype': ['Cup', 'Chair', 'fan']}, 
 2: {'date': ['05MAY14', '13MAY14', '16MAY14'], 'objecttype': ['Home', 'Desk', 'Pencil']}, 
 3: {'date': ['14MAY14', '14MAY14', '04MAY14'], 'objecttype': ['Cup', 'Stationery', 'Book']}, 
 4: {'date': ['15MAY14', '15MAY14', '01MAY14'], 'objecttype': ['Eraser', 'Pen', 'Notebook']}}
Related