1

I've been struggling with how to loop through a list, adding 0 for the missing months back in to the original dictionary. I am thinking to create a list of months, from calendar, loop through each of those, then loop through each month in my data...but can't quite figure out how to update the dictionary when there's a missing month in correct order.

import calendar

my_dict = {'Green Car': 
        [('January', 340), 
        ('February', 2589), 
        ('March', 12750), 
        ('April', 114470), 
        ('July', 4935),
        ('August', 1632),
        ('September', 61),
        ('December', 3409)], 
    'Red Truck': 
        [('January', 2325185), 
        ('February', 209794), 
        ('March', 201874),
        ('April', 19291),
        ('May', 18705), 
        ('July', 22697), 
        ('August', 22796)], 
    'Police Car': 
        [('January', 2037), 
        ('February', 2620), 
        ('March', 1480), 
        ('April', 15630), 
        ('July', 40693), 
        ('August', 2329)], 
    'Zamboni': 
        [('January', 256), 
        ('February', 426690), 
        ('March', 589), 
        ('April', 4740), 
        ('May', 880), 
        ('July', 1016), 
        ('August', 106), 
        ('September', 539), 
        ('October', 598), 
        ('November', 539), 
        ('December', 470)], 
    'Witch Broom': 
        [('February', 350),
        ('March', 3520), 
        ('October', 2703), 
        ('November', 2221), 
        ('December', 664)]
    }


def fill_months(reported_months):
    const_months = list(calendar.month_name)
    x = 0
    print("Looking for months in", reported_months) 
    # print(const_months)
    for const_month in const_months:
        for month in reported_months:
            if const_month != month[0] and len(const_month) > 0:
                print(const_month, month[0])
                print("You don't have", const_month, "in the months group:", reported_months)


def main():
    for commod, months in my_dict.items():
        # print(commod)
        # print(commod, months)
        fill_months(months)


if __name__ == '__main__':
    main()

For each key ("Green Car", "Red Truck", etc.) I want to loop through and add in a missing moth with the value 0. So the "Green Car" in the end would turn out to be:

my_dict = {'Green Car': 
        [('January', 340), 
        ('February', 2589), 
        ('March', 12750), 
        ('April', 114470),
        ('May', 0),
        ('June', 0),
        ('July', 4935),
        ('August', 1632),
        ('September', 61),
        ('October', 0),
        ('November', 0),
        ('December', 3409)], 

I'm getting somewhere with this - but the logic feels kind of kludgy:

def fill_months(reported_months):
    const_months = list(calendar.month_name)
    x = 0
    temp_months = []
    for i in reported_months:
        temp_months.append(i[0])
    print("Looking for months in", reported_months) 
    # print(const_months)
    for const_month in const_months:
        if len(const_month) > 0:
            if const_month not in temp_months:
                reported_months.insert(x-1, (const_month, 0))
        x += 1
    print(reported_months)
miradulo
  • 28,857
  • 6
  • 80
  • 93
BruceWayne
  • 22,923
  • 15
  • 65
  • 110

3 Answers3

1

This will add the months to your list and then sort the monthlists

# remove the leading empty '' from calendar.month_name list
monthnames = [x for x in calendar.month_name if x != ''] 

# scan dicts for missing monts, if found, append tuple (monthname,0) to list
for part in my_dict:
    print(part)
    for month in monthnames:
        if not month in [x[0] for x in my_dict[part]]:
            my_dict[part].append( (month,0) ) 

# modified https://stackoverflow.com/questions/10695139/sort-a-list-of-tuples-by-2nd-item-integer-value
# interrate through dict, assign sorted dict, use indexlookup into monthlist for sorting
for part in my_dict:
    my_dict[part] = sorted(my_dict[part], key=lambda x: monthnames.index(x[0]))

print(my_dict)

Output:

{'Red Truck'
    : [('January', 2325185)
        ,( 'February', 209794)
        ,( 'March', 201874)
        ,( 'April', 19291)
        ,( 'May', 18705)
        ,( 'June', 0)
        ,( 'July', 22697)
        ,( 'August', 22796)
        ,( 'September', 0)
        ,( 'October', 0)
        ,( 'November', 0)
        ,( 'December', 0)], 
'Witch Broom'
    : [('January', 0)
        ,( 'February', 350)
        ,( 'March', 3520)
        ,( 'April', 0)
        ,( 'May', 0)
        ,( 'June', 0)
        ,( 'July', 0)
        ,( 'August', 0)
        ,( 'September', 0)
        ,( 'October', 2703)
        ,( 'November', 2221)
        ,( 'December', 664)], 
'Police Car'
    : [('January', 2037)
        ,( 'February', 2620)
        ,( 'March', 1480)
        ,( 'April', 15630)
        ,( 'May', 0)
        ,( 'June', 0)
        ,( 'July', 40693)
        ,( 'August', 2329)
        ,( 'September', 0)
        ,( 'October', 0)
        ,( 'November', 0)
        ,( 'December', 0)], 
'Green Car'
    : [('January', 340)
        ,( 'February', 2589)
        ,( 'March', 12750)
        ,( 'April', 114470)
        ,( 'May', 0)
        ,( 'June', 0)
        ,( 'July', 4935)
        ,( 'August', 1632)
        ,( 'September', 61)
        ,( 'October', 0)
        ,( 'November', 0)
        ,( 'December', 3409)], 
'Zamboni'
    : [('January', 256)
        ,( 'February', 426690)
        ,( 'March', 589)
        ,( 'April', 4740)
        ,( 'May', 880)
        ,( 'June', 0)
        ,( 'July', 1016)
        ,( 'August', 106)
        ,( 'September', 539)
        ,( 'October', 598)
        ,( 'November', 539)
        ,( 'December', 470)]}
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

All that the logic adding missing months has to check for is if months don't match by index to some list of month names you have, months. Increment if they do match, and loop until every member of months is covered.

months = ['January', 'February', 'March', 'April', 'May', 'June', 
          'July', 'August', 'September', 'October', 'November', 'December']

def add_missing_months(vehicle_d):    
    for vehicle in vehicle_d:
        ind = 0
        month_l = vehicle_d[vehicle]
        while ind < len(months):
            if ind >= len(month_l) or month_l[ind][0] != months[ind]:
                month_l.insert(ind, (months[ind], 0))
            else:
                ind += 1
    return vehicle_d
miradulo
  • 28,857
  • 6
  • 80
  • 93
0

You can use sets difference to get which months are missing in your reported_month and then add them with 0 to your list.

filter with bool is used to remove empty string from the list.

import calendar


my_dict = {
'Green Car':
        [('January', 340),
        ('February', 2589),
        ('March', 12750),
        ('April', 114470),
        ('July', 4935),
        ('August', 1632),
        ('September', 61),
        ('December', 3409)],
    'Red Truck':
        [('January', 2325185),
        ('February', 209794),
        ('March', 201874),
        ('April', 19291),
        ('May', 18705),
        ('July', 22697),
        ('August', 22796)],
    'Police Car':
        [('January', 2037),
        ('February', 2620),
        ('March', 1480),
        ('April', 15630),
        ('July', 40693),
        ('August', 2329)],
    'Zamboni':
        [('January', 256),
        ('February', 426690),
        ('March', 589),
        ('April', 4740),
        ('May', 880),
        ('July', 1016),
        ('August', 106),
        ('September', 539),
        ('October', 598),
        ('November', 539),
        ('December', 470)],
    'Witch Broom':
        [('February', 350),
        ('March', 3520),
        ('October', 2703),
        ('November', 2221),
        ('December', 664)]
    }


def filter_month(x, months):
    """filters the month when month[i] == x
    """
    return [i[1] for i in months if i[0] == x][0]

def fill_months(reported_months):
    const_months = list(filter(bool, calendar.month_name))
    my_months = set(map(lambda x: x[0], reported_months))
    missing_months = set(const_months) - my_months

    for month in missing_months:
        reported_months.append((month, 0))

    # arranging
    arranged = list(map(lambda x: (x, filter_month(x, reported_months)), const_months))
    for i in range(len(reported_months)):
        reported_months[i] = arranged[i]

def main():
    for commod, months in my_dict.items():
        fill_months(months)

if __name__ == '__main__':
    main()
Moiz Farooq
  • 1,018
  • 9
  • 11
  • This works, although it adds the months to the end. Is there a way to keep the sorting and insert the month where it should be chronologically? – BruceWayne Nov 20 '17 at 19:20