Home > Blockchain >  Avoid using if statements for checking keys in dict
Avoid using if statements for checking keys in dict

Time:12-04

I am trying to map some values from data to a template.
I want to fill in the values (with some manipulations) in the template only if they are already present in it.
My template has hundreds of keys and my goal is to avoid the if statement before each manipulation and assignment

data = {
    'a':1,
    'b':2,
    'c':3,
    'd':4,
    'e':5
}

template1 = {
    'p':'Nan',
    'q':'Nan',
    'r':'Nan'
}

template2 = {
    'p':'Nan',
    's':'Nan',
    't':'Nan'
}

def func(template,data):
    if 'p' in template.keys():
        template['p'] = data['a']
    if 'q' in template.keys():
        template['q'] = data['b'][:2]   'some manipulation'
    if 'r' in template.keys():
        template['r'] = data['c']
    if 's' in template.keys():
        template['s'] = data['d']   'some mainpulation'
    if 't' in template.keys():
        template['t'] = data['e']

I know I am missing something basic, my actual code and requirements are pretty complex and I tried to simplify them and bring them down to this simple structure. Thanks for your help in advance!

CodePudding user response:

You could also store manipulations directly in your data dict using lambda functions, then check if any retrieved value from the data dict is callable() when using this dict to update the template. Assuming your can't modify the keys in the data dict, then this approach could still work with the template_dict mapping approach suggested by Jlove.

data = {
    'p': 1,
    'q': 2,
    'r': 3,
    's': 4,
    't': 5,
    'u': lambda x: x * 2
}

template1 = {
    'p':'Nan',
    'q':'Nan',
    'r':'Nan',
    'u': 2
}


def func(template, data):
    for key in template:
        if callable(data[key]):
           template[key] = data[key](template[key])
        else:
            template[key] = data[key]

#driver
func(template1, data)

for k in template1.items():
    print(k)

CodePudding user response:

The only thing I could think to do here would be to have some sort of dict and run your template through a for loop instead. Such as:

template_dict = {'p': 'a', 'q': 'b', 'r': 'c', 's': 'd', 't': 'e'}

def func(template, data):
    for key, value in template_dict.items():
        if key in template.keys():
            template[key] = data[value]

Otherwise, I'm not sure how you might be able to avoid all those conditionals.

CodePudding user response:

a dynamically functional approach might relieve you from all the ifs and elses, but might complicate the overall program structure.

data = {
    'a':1,
    'b':2,
    'c':3,
    'd':4,
    'e':5
}

template1 = {
    'p': 'Nan',
    'q': 'Nan',
    'r': 'Nan'
}

template2 = {
    'p': 'Nan',
    's': 'Nan',
    't': 'Nan'
}

# first, define your complex logic in functions, accounting for every possible template key


def p_logic(data, x):
    return data[x]


def q_logic(data, x):
    return data[x][:2]   'some manipulation'

# Then build a dict of every possible template key, the associated value and reference to one of the
# functions defined above


logic = {
    'p': {
        'value': 'a',
        'logic': p_logic
    },
    'q': {
        'value': 'b',
        'logic': q_logic
    },
}


def func(template, data):
    # for every key in a template, lookup that key in our logic dict
    # grab the value from the data
    # and apply the complex logic that has been defined for this template value 
    for item in template:  # template.keys() is not necessary!
        template[item] = logic[item]['logic'](data, logic[item]['value'])
  • Related