Best practices for using Python if-elif-elif-elif when sending requests

I have 5 sets of query categories defined as python dicts, for example:

category1 = {'type1', 'type2', 'type3'} category2 = {'type4', 'type5'} category3 = {'type6', 'type7', 'type8', 'type9'} category4 = {'type10', 'type11'} category5 = {'type12', 'type13', 'type14'} 

And I need to process requests using their category, for example:

 if request_type in category1: # process category1 request process_category1_request(...) elif request_type in category2: # process category2 request process_category2_request(...) elif... 

and I need to send the request using the request type to another function to handle it.

I already know that there are ways to send these requests to Python without using if-elif, but my question is: what is the best way to do this while keeping the code clean and simple?

+6
source share
5 answers

If request_type can be present in more than one category, you can use the tuple to scroll them in order of priority:

 categories = ( (category1, dispatch1method), (category2, dispatch2method), (category3, dispatch3method), (category4, dispatch4method), (category5, dispatch5method), ) next(method for cat, method in categories if request_type in cat)(arguments) 

Otherwise, use dict() to map category types to submit methods; reuse of the same tuple-tuple to create a dispatch:

 category_dispatch = {} for cat, dispatch in categories: category_dispatch.update(dict.fromkeys(cat.keys(), dispatch)) 

Then just find the type of request:

 category_dispatch[request_type](arguments) 

Such a matching search will be faster than scanning through a tuple, where we must test each category in turn until we find a match.

In fact, the order of priorities can be maintained by changing the same tuple structure as follows:

 category_dispatch = {} for cat, dispatch in reversed(categories): category_dispatch.update(dict.fromkeys(cat.keys(), dispatch)) 

since now the highest priority mapping for this key request_type will be introduced into the category_dispatch last structure. This will give you the fastest sending, even if request types were present in several categories.

The disadvantage is that if your category* mappings are dynamic (query types are added and removed from different categories over time), you need to maintain a category_dispatch dict to reflect these changes.

+14
source

I think the cleanest can be two cards to make the code the most readable.

 type_category_map = {"type1" : "category1", "type2" : "category1", , "type3" : "category1", "type4" : "category2", .... "type14" : "category5"} category_function_map = {"category1" : "handler1_function", "category2" : "handler2_function, .... } 

Then python will be as follows:

 category = type_category_map[request_type] handler_function = category_function_map[category] handler_function(request) 

There would be ways to do this with a single data structure, but none of them would be as clear and easy as I think.

+4
source

Match your categories with a handler. Regardless of the size of the card you will have O (1).

 MAP = { 'cat1': handler1, 'cat2': handler2, .... } MAP[request_type](...) 
+3
source

You cannot specify a dict, for example

category1 = {'type1', 'type2', 'type3'}

you have no key meanings.

How is the question for you, is this a simple solution for you?

 dispatchers = {} def register_dispatches(types, dispatcher): dispatchers.update(dict.fromkeys(types, dispatcher)) def process(request_type, *args, **kwargs): dispatchers[request_type](*args, **kwargs) register_dispatches(['type1', 'type2', 'type3'], process_category1_request) register_dispatches(['type4', 'type5'], process_category2_request) ... process(request_type, ...) 
+3
source
 categories = {request1 : dispatch1, request2 : dispatch2, request3 : dispatch3} for category, dispatch in categories.iteritems(): if something in category: dispatch(something) 

How about this?

+2
source

All Articles