0

I am not sure on the precise way to phrase the question as it is easier to just demonstrate with code. I would like to have a function that accepts a variable number of a set of 3 required and 1 optional arguments. As an illustration, matplotlib.pyplot.plot() can accept any number of (x, y, color) set of variables. I would like to copy this behavior, but I am unsure of the proper way to do this using *args or similar. Below I illustrate the behavior I would like.

myFunc(name, lo, hi, step) # Do something
myFunc(name, lo, hi, step, name2, low2, hi2, step2) # Do something for name and name2
myFunc(name, lo, hi, name2, low2, hi2) # Same as above but use default step for both

The only way I can think of is to loop through the arguments and perform a series of checks on make sure it satisfies the type for (name, lo, hi, step) and to check if step is even given, but I would like to know if there is a more efficient way of doing this.

Edit:

I wanted the above behavior since my function uses the first set to identify a parameter and create a while loop. If any more sets of parameters remain it calls itself recursively to construct a nested while loop with the remaining parameters, etc. If no additional sets remain it will perform some data measurement and then return. This way I can loop through an arbitrarily large multi-dimensional space using a single recursive function.

Snyder005
  • 224
  • 2
  • 8
  • Perhaps you want **kwargs. These will allow you optional keyword arguments – Garrett R Feb 12 '16 at 20:42
  • There are parts of the `matplotlib` api that I find to be really awful -- This is one of them. :-). In this case, I'd recommend having the function/method called a number of times with 3 required and 1 optional argument. . . Would that be possible for your use case? – mgilson Feb 12 '16 at 20:43
  • Check this post: http://stackoverflow.com/questions/3394835/args-and-kwargs – Alex Feb 12 '16 at 20:46
  • I might be able to just use *args since the recursive nature of the function means I only have to check the first 4 args and then see if any more exist. – Snyder005 Feb 12 '16 at 21:13
  • In response to your edit -- why have the user pass an iterable of `(name, low, hi, [step])`? – mgilson Feb 12 '16 at 21:17
  • I use name to identify which parameter, and the rest specify the array of values for that parameter. I may want to perform some measurement on every point in x = [0, 1, 2, 3, 4] or every point in 2d grid of x, y = [0, 1, 2, 3, 4], or every point in a 6d grid where I have 6 parameters each has a unique array of points. My other thought is to make a big numpy grid array, but for each point in the phase space I need a particular measurement function run and I'm not sure how to do this with numpy. – Snyder005 Feb 12 '16 at 21:26

1 Answers1

0

Is something like this what you're looking for?

list_of_things = [('name', 'lo', 'hi', 'step'),
                  ('name2', 'lo2', 'hi2'), 
                  ('name3', 'lo3', 'hi3', 'step3')
]
def myFunc(name, lo, hi, step='default'):
                              # do something
def callMyFunc(x):    
    for i in x:
        myFunc(*i)            # pass the contents of the tuple as arguments

If you don't want the tuple of items ordered, you would have to name each of the arguments and submit them named.

jlbnjmn
  • 958
  • 7
  • 5
  • Sort of, but I need the for loop inside the function, so to speak. Basically I check how many of the tuples I have, and the function changes depending on how many have been passed. More specifically it processes the first set and if any more tuples remain I recursively call the function. – Snyder005 Feb 12 '16 at 21:07
  • I've edited it to place the for loop inside of a second function. Calling that function with the list will process each tuple inside one by one. Based on your updated question, this may not help. – jlbnjmn Feb 12 '16 at 22:02