views:

124

answers:

4

I have a set of functions:

functions=set(...)

All the functions need one parameter x.

What is the most efficient way in python of doing something similar to:

for function in functions:
   function(x)
+1  A: 

If you need the output, a list comprehension would work.

[func(x) for func in functions]
Stefan Kendall
A: 

I'm somewhat doubtful of how much of an impact this will have on the total running time of your program, but I guess you could do something like this:

[func(x) for func in functions]

The downside is that you will create a new list that you immediatly toss away, but it should be slightly faster than just the for-loop.

In any case, make sure you profile your code to confirm that this really is a bottleneck that you need to take care of.

Epcylon
There's no particular reason that a list comprehension should be faster than the `for` loop. Such claims require benchmarks.
Greg Hewgill
http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loops seems to indicate that there is a particular reason, namely that the loop gets pushed into compiled C code. True, there are other factors that also contribute, which is why I told him to profile.
Epcylon
+7  A: 
Stephan202
+1 for the "Avoid functions with side-effects in list-comprehensions" reminder.
semiuseless
Especially since the order of iterating over set members is not defined
Ber
A: 

Edit: I redid the test using timeit

My new test code:

import timeit

def func(i):
    return i;

a = b = c = d = e = f = func

functions = [a, b, c, d, e, f]

timer = timeit.Timer("[f(2) for f in functions]", "from __main__ import functions")
print (timer.repeat())

timer = timeit.Timer("map(lambda f: f(2), functions)", "from __main__ import functions")
print (timer.repeat())

timer = timeit.Timer("for f in functions: f(2)", "from __main__ import functions")
print (timer.repeat())

Here is the results from this timing.

testing list comprehension
[1.7169530391693115, 1.7683839797973633, 1.7840299606323242]

testing map(f, l)
[2.5285000801086426, 2.5957231521606445, 2.6551258563995361]    

testing plain loop
[1.1665718555450439, 1.1711149215698242, 1.1652190685272217]

My original, time.time() based timings are pretty much inline with this testing, plain for loops seem to be the most efficient.

Bryan McLemore