I want to make a function that is flexible with regard to unpacking the number of input variables.
More specifically, for example I have the following:
def flexi_func(vars):
func_var_a, func_var_b, func_var_c, func_var_d = vars
#do something
my_vars = [var_a, var_b, var_c, var_d]
flexi_func(my_vars)
This works fine if the number of input variables is 4. But say I want to have the same function operate on just three input variables, or two. Assume the 'do something' bit is already flexible. Then to unpack the variables I can write
def flexi_func(vars):
if len(vars) == 4:
func_var_a, func_var_b, func_var_c, func_var_d = vars
elif len(vars) == 3:
func_var_a, func_var_b, func_var_c = vars
elif len(vars) == 2:
func_var_a, func_var_b = vars
#do something
And this works fine too. It just seems a bit clunky to me, especially if I had N>4 variables. Is there a cleaner, more Pythonic way to unpack a tuple in such a way that I can use the unpacked variables?
I know from this question I can do something like this (in Python 3):
foo, bar, *other = func()
but I would need to do more work to access the stuff in other
, so it's no better than my if...elif...
approach.
Firstly, in response to the comments asking for context or a concrete example where this might be necessary, I concede that in almost all the cases I can think of it should be possible to avoid unpacking altogether. This goes for my original problem too - the do something
part of the function can be modified to access the items through list indices.
However, in principle, I am sure there exist situations where unpacking is needed, even if only for clarity. Below is the best way I can find to assign a variable to each input item. More background detail is given in the answers here and here.
def flexi_func(var_list):
for i, var in enumerate(var_list):
vars()['my_func_{}'.format(i)] = var
#do something
return
This assigns each input variable to the vars()
built-in dictionary. This is preferable to the globals()
built-in dictionary and is writable unlike the locals()
built-in dictionary. To access the variables in the do something
section, you have to reference the dictionary like so: print(vars()['my_func_2'])
.
Finally, if you want to use letters as variable labels instead of numbers (as I did in my problem statement) you can add alphabet = [chr(i) for i in range(ord('a'),ord('z')+1)]
to the top of the function and call the variables 'my_func_{}'.format(alphabet[i])
.