Storing functions in a dictionary [Python]

I am currently creating an application in which I need to iterate through a series of steps that do basically the same thing, except for a very small amount of code (~ 15 lines). The number of steps will vary depending on how the project is configured, so it seems silly to me to create a separate function for each potential instance.

In JavaScript, I would do something like this:

var switches = [true, true, false, true]; var holder = { 0: function() { /* do step0 */ } 1: function() { /* do step1 */ } 2: function() { /* do step2 */ } 3: function() { /* do step3 */ } // ...etc... } for (var i = 0; i < switches.length; i++) if (switches[i]) holder[i](); 

Is there a way to do something like this in python? The only thing I can think of is something like this:

 switches = [True, True, False, True] class Holder(object): @staticmethod def do_0(): # do step0 @staticmethod def do_1(): # do step 1 # ...etc... def __repr__(self): return [self.do_0, self.do_1, ...] for action in Holder: action() 

It seems terribly inefficient if I have a significant number of steps. Is there a better way to do this?

+8
javascript python dictionary arrays data-structures
source share
4 answers

There seems to be no way in Python to do this, the design decision was intentional, as it was rejected as non-Pythonic. Well, it looks like I'm stuck defining methods and then manually adding them to the list for iteration.

Source: https://softwareengineering.stackexchange.com/a/99245

+2
source share

You can do it as follows:

 # define your functions def fun1(): print("fun1") def fun2(): print("fun2") def fun3(): print("fun3") switches = [True, False, True]; # put them in a list (list makes more sense than dict based on your example) func_list = [fun1, fun2, fun3] # iterate over switches and corresponding functions, and execute # functions when s is True for s,f in zip(switches, func_list): if s: f() 

This is the only way. There are many others. e.g. using lambdas, dict as you like, etc.

To use lambdas if your functions are only one line you can do:

 func_list = [lambda: print("lambda1"), lambda: print("lambda2"), lambda: print("lambda1")] 
+3
source share
 - Your functions don't need to be enveloped in a utility class. - I don not see how the two blocks of code differ in efficiency. - You can use enumerate and lambdas to simplify your code. 

Simplified code

 d = {0: lambda: 'Performing Step 0', 1: lambda: 'Performing Step 1', 2: lambda: 'Performing Step 2', 3: lambda: 'Performing Step 3', 4: lambda: 'Performing Step 4'} for index, switch in enumerate([1, 0, 1, 1, 0]): if switch == 1: d[index]() 
+1
source share

I usually say this as follows. I like this approach because it adds minimal overhead to the code, and if you write an additional method later, nothing needs to be changed elsewhere in the file.

 def steptest0(): code def steptest1(): code def steptest2(): code ... tests = filter(lambda x: x.startswith('steptest'), dir()) for t in tests: eval(t + '()') 

Each method is already automatically placed in the dictionary in Python, and dir() allows us to access this.

Denial of responsibility. There are some troubling bells that begin to go to the head of the average fanatical infantryman at the sight of β€œeval,” and some may even have cramps. Let them protect themselves from eval by using the reflection mechanism instead (which may make it less readable, but still worth it, since they cannot be blamed for using "eval").

-one
source share

All Articles