Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - list of function/argument tuples

def f1(n): #accepts one argument
    pass

def f2(): #accepts no arguments
    pass

FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments
                 (f1,(6)),
                 (f2,())]

for f, arg in FUNCTION_LIST:
    f(arg)

The third time round in the loop, it attempts to pass an empty tuple of arguments to a function that accepts no arguments. It gives the error TypeError: f2() takes no arguments (1 given). The first two function calls work correctly - the content of the tuple gets passed, not the tuple itself.

Getting rid of the empty tuple of arguments in the offending list entry doesn't solve the problem:

FUNCTION_LIST[2] = (f2,)
for f,arg in FUNCTION_LIST:
    f(arg)

results in ValueError: need more than 1 value to unpack.

I've also tried iterating over the index rather then the list elements.

for n in range(len(FUNCTION_LIST)):
    FUNCTION_LIST[n][0](FUNCTION_LIST[n][1])

This gives the same TypeError in the first case, and IndexError: tuple index out of range when the third entry of the list is (f2,).

Finally, asterisk notation doesn't work either. This time it errors on the call to f1:

for f,args in FUNCTION_LIST:
    f(*args)

gives TypeError: f1() argument after * must be a sequence, not int.

I've run out of things to try. I still think the first one ought to work. Can anyone point me in the right direction?

like image 391
Benjamin Hodgson Avatar asked Aug 09 '12 12:08

Benjamin Hodgson


People also ask

How to expand list or tuple to function arguments in Python?

Expand and pass list, tuple, dict to function arguments in Python. In Python, you can expand list, tuple, dict (dictionary) and pass each element to function as arguments by adding * to list or tuple and ** to dictionary when calling function. This article describes the following contents.

How do you pass a tuple as an argument in Python?

Example: Pass a Tuple as an Argument using *args Syntax This method of passing a tuple as an argument to a function involves unpacking method. Unpacking in Python uses *args syntax. As functions can take an arbitrary number of arguments, we use the unpacking operator * to unpack the single argument into multiple arguments.

How to create a list of tuples from list in Python?

Here, list_data is the input list to create a list of tuples, list is a predefined function and tuple is a predefined function Example: Python code to create a list of tuples from the list using map () function

How do you get multiple arguments from a function in Python?

As functions can take an arbitrary number of arguments, we use the unpacking operator * to unpack the single argument into multiple arguments. This is a special way of receiving parameters to a function as a tuple.


2 Answers

Your comment in this code snippet shows a misconception relevant in this context:

FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments
                 (f1,(6)),
                 (f2,())]

The expressions (2) and (6) are not tuples – they are integers. You should use (2,) and (6,) to denote the single-element tuples you want. After fixing this, your loop code should look thus:

for f, args in FUNCTION_LIST:
    f(*args)

See Unpacking Argument Lists in the Python tutorial for an explanation of the *args syntax.

like image 179
Sven Marnach Avatar answered Oct 20 '22 21:10

Sven Marnach


The problem is that such notation:

(6)

evaluates to integer value and you need tuple, so write this way:

(6, )

and your asterisk notation will succeed.

like image 29
Rostyslav Dzinko Avatar answered Oct 20 '22 21:10

Rostyslav Dzinko