Othman
Othman

Reputation: 3018

How to generate a dictionary based on a list and dictionaries

I have two dictionaries. One dictionary is for employee service years. The other dictionary is for manual rules for the paid time-off days in a year or less than this year. Also a variable that contain the number of the default paid time-off days for an employee.

List1 (Employee Service Years)

[1,2,3,4,5,6,7,8,9,10]

this means that the employee worked for 10 full years.

Dictionary (Employee Time-Off Paid Days Rules)

{
 3: 15,
 6: 21
}

What this dictionary mean is that the employee for the first 3 years will receive 15 days. Then the next three years will receive 21 days. the rest will be equal to the default which is a variable = 30 called defaultPaidTimeOffDays

Output Needed:

{
 1: 15,
 2: 15,
 3: 15,
 4: 21,
 5: 21,
 6: 21,
 7: 30,
 8: 30,
 9: 30,
 10: 30
}

Current Code

def generate_time_off_paid_days_list(self, employee_service_years, rules, default):

    if not rules:
        dic = {}
        for y in employee_service_years:
            dic[y] = default
    else:
        dic = {}
        last_change = min(rules)
        for y in employee_service_years:
            if y in rules:
                last_change = rules[y]
            dic[y] = last_change

    return dic

But I am stuck with getting if bigger = default

Upvotes: 0

Views: 52

Answers (1)

dano
dano

Reputation: 94881

Here's a way to do it that leverages the bisect module to determine which rule to use for each year:

import bisect

rules = {
 3: 15,
 6: 21
}

def generate_time_off_paid_days_list(years, rules, default):
    r_list = rules.keys()
    r_list.sort()  # sorted list of the keys in the rules dict
    d = {}
    for y in years:
        # First, find the index of the year in r_list that's >= to "y"
        r_index = bisect.bisect_left(r_list, y)
        if r_index == len(r_list):
            # If the index we found is beyond the largest index in r_list, 
            # we use the default
            days_off = default
        else: 
            # Otherwise, get the year key from r_list, and use that key to
            # retrieve the correct number of days off from the rules dict
            year_key = r_list[r_index]
            days_off = rules[year_key]
        d[y] = days_off
    return d

print generate_time_off_paid_days_list(range(1,11), rules, 30)

Output:

{1: 15, 2: 15, 3: 15, 4: 21, 5: 21, 6: 21, 7: 30, 8: 30, 9: 30, 10: 30}

And a more compact, but much less readable version:

from bisect import bisect_left

def generate_time_off_paid_days_list(years, rules, default):
    r_list = sorted(rules)
    d = {y : default if y > r_list[-1] else 
             rules[r_list[bisect_left(r_list, y)]] for y in years}
    return d

Upvotes: 1

Related Questions