1

I've been looking for ways to avoid long "for" loops as I'll be dealing with mesh operations and was wondering if there was a way to make an array of functions. Something like the following would be nice.

x=np.array([1,2,3,4,5])
funcs=np.array([func1,func2,func3,func4],dtype=function)

output=funcs(x)
Jai
  • 819
  • 7
  • 17
Cam K
  • 127
  • 2
  • 2
  • 13
  • Why an array and not just a list? – yatu Mar 10 '20 at 11:44
  • 1
    Does this answer your question? [Calling functions by array index in Python](https://stackoverflow.com/questions/5707589/calling-functions-by-array-index-in-python) – Bando Mar 10 '20 at 11:45
  • This really looks like an XY problem https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – ChatterOne Mar 10 '20 at 11:48
  • Hey Bandoleras, that would still involve using a for loop, which is what I'm trying to avoid! – Cam K Mar 10 '20 at 11:53
  • 'avoiding loops' in a `numpy` context really means 'do the loops in compiled code'. There's a lot you can do with numeric dtype arrays. But your `funcs` is object dtype (look at it!). Most math on object arrays uses python level iteration (explicit or hidden). In any case, there's no `numpy` functionality that will do `[func1(1), func2(2), ....]` – hpaulj Mar 10 '20 at 16:35

1 Answers1

3

You can just create a list of functions and then use a list comprehension for evaluating them:

x = np.arange(5) + 1
funcs = [np.min, np.mean, np.std]
output = [f(x) for f in funcs]

If you really think that funcs(x) reads nicer in your code, you can create a custom class that wraps the above logic:

class Functions:
    def __init__(self, *funcs):
        self.funcs = funcs

    def __call__(self, *args, **kwargs):
        return [f(*args, **kwargs) for f in self.funcs]

funcs = Functions(np.min, np.mean, np.std)
output = funcs(x)
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • Hey, this looks amazing! It still uses a for loop though, which is what I was trying to avoid! Is there any way to avoid using a for loop? In Python, for loops really slow down my code especially with lots of mesh elements. – Cam K Mar 10 '20 at 12:31
  • @CamK No, they don't slow down your code. A list comprehension is as fast as it can get. The required memory is known from the start and the loop itself runs in C. These function calls happen in Python so you can't get around that. I suppose you're not calling that many functions anyway? – a_guest Mar 10 '20 at 12:52
  • I was thinking this might be handy if I wanted to treat each element/cell in a mesh differently. A function for each object type wouldn't be so bad. A function for each mesh element would be in the thousands! I've found a way around using another for loop, but this is good to have! Thank you! – Cam K Mar 10 '20 at 12:55