horcle_buzz
horcle_buzz

Reputation: 2171

Expressions in a dictionary mapping

I have a series of conditionals of the form:

if ':' in particle:
    do something
elif 'eq' in particle:  
    do something else
elif 'lt' in particle:
    do another thing
elif 'le' in particle:
    etc.
elif 'gt' in particle:
    etc., etc.
elif 'ge' in particle:
    etc., etc., etc.
elif 'ne' in particle:
    more etc.

I want to implement this using a dictionary mapping pattern, but am having issues with the keys.

I tried this:

def case_evaluator(particle):
    switcher = {
        ':' in particle: do something,
        'eq' in particle: do something else,
        'lt' in particle: do another thing,
        ...
    }
    return switcher.get(particle, "nothing")

But, I kept getting "nothing." How can something give nothing?

This seems like it should be simple, but alas...

Upvotes: 0

Views: 102

Answers (2)

Robin Davis
Robin Davis

Reputation: 632

You're on the right track. This is called function dispatch. It needs to look more like this:

def case_evaluator(particle):
    switcher = {
        ':': do_something,
        'eq': do_something_else,
        'lt': do_another_thing,
        ...
    }
    return switcher.get(particle, lambda: "nothing")()

where do_something, etc are all functions that take no arguments. The lambda x: "nothing" is a lambda function that just always returns "nothing" -- it's the default function to be called if particle isn't found in switcher.keys().

Upvotes: 2

Jared Goguen
Jared Goguen

Reputation: 9008

You probably want to have a dictionary that maps characters to functions.

char_function_dict = {
    ':': colon_function,
    'eq': eq_function,
    'lt': lt_function
    # ...and so on...
}

Then, you can iterate over the key-value pairs in this dictionary.

def apply_function(particle):
    for char, function in char_function_dict.items():
        if char in particle:
            function()

However, note that this structure doesn't really use anything specific to dictionaries and doesn't preserve the order that the characters are checked. It would perhaps be even more simple to use a list of 2-element tuples.

char_functions = [
    (':', colon_function),
    ('eq', eq_function),
    ('lt', lt_function)
    # ...and so on...
]

def apply_function(particle):
    for char, function in char_functions:
        if char in particle:
            function()
            break # so successive functions are not run

Setting up either of these structures to allow arguments and/or keyword arguments to be passed to the functions is easy:

def apply_function(particle, *args, **kwargs):
    for char, function in char_functions:
        if char in particle:
            function(*args, **kwargs)
            break

Upvotes: 2

Related Questions