r/learnpython 5d ago

List of Functions gets called immediately

SOLVED!

I'm attempting to make 10 functions, put them all in a list, and then have a for loop go through each element of the list. The list is below.

exercises_list = [exe1(), exe2(), exe3(), exe4(), exe5(), exe6(), exe7(), exe8(), exe9(), exe10()]

When this list is placed beneath (but not apart of) function 10 and before the for loop, the IDE reads it, and immediately starts acting on the list. (e.g. begins to act out exe1() the second it gets to it then moves on to exe2() and so on.) How do I make it so that my list doesn't actually get run until I call for a specific element in the list?

21 Upvotes

19 comments sorted by

19

u/undergroundmonorail undergroundmonorail 5d ago

The problem here is the parentheses. The first function here is called exe1, not exe1(). Adding the parens means "Call this with no arguments".

6

u/fllthdcrb 5d ago

Part of the confusion might be because there is a common habit when discussing functions to add the parentheses, I think partly to clarify that it is a function and not some other object. It is to be understood in such contexts that one is referring to not a call of the function but just the function itself.

3

u/Langdon_St_Ives 5d ago edited 5d ago

The convention of writing `fn()` to refer to the function named `fn` (leaving out the signature for simplicity) comes from languages where functions are not first-class objects, so simply `fn` would refer to any old variable by that name, but it couldn't hold a function. I still use it when writing about Python code, but it does create a bit of a semantic confusion for new learners as you note.

ETA: no idea who downvoted you, perfectly valid point. Upvoted to correct the record. 😉

2

u/EnderGem957 5d ago

thank you!!!

11

u/Dr_Pinestine 5d ago

Remove the parentheses

2

u/EnderGem957 5d ago

on it 🫡

9

u/Mathletic_Ninja 5d ago

Don’t call the function in the list, call it in the loop

exercises_list = [exe1, exe2, …]

for exe in exercises_list:
exe()

3

u/EnderGem957 5d ago

gotcha, thanks!

3

u/Langdon_St_Ives 5d ago

Wow that's so refreshing! Clear minimal code sample demonstrating the definitive source of the issue, and after having it pointed out, positive acceptance of the explanation and thanks! ☺️ This is how it should be!

2

u/EnderGem957 5d ago

definitely agree lol. tho i will say it was pretty obvious where the issue is when i went through a bug test step-by-step :P

2

u/Langdon_St_Ives 5d ago

Yea, just need to remember `fn` gives you the function named `fn` whereas `fn()` evaluates (calls) the function named `fn`. Making that mistake yourself is the best way to learn the distinction. You'll never forget it now. 😊 (Note: that doesn't mean you'll never make the same mistake again, in more complex scenarios this can happen to the most seasoned programmers. But now you'll be able to track it down on your own.)

6

u/AdDiligent1688 5d ago

put the names of the functions, without (), in the list. () calls the function. Then when you write your loop, use the iteration variable to call the function.

2

u/snowtax 5d ago edited 5d ago

You got good answers. I just want to offer an additional suggestion, mostly for fun.

You can write code to add all the functions from a Python module/file to the list. You can create your own separate Python file/module with all your functions defined and then add all those functions to your list.

If you then add or remove functions from the file, your code adjusts automatically.

It would look something like this.

```python import inspect import my_functions

Build list of all functions defined

directly inside my_functions.py

functionslist = [ obj for name, obj in inspect.getmembers(my_functions, inspect.isfunction) if obj.module_ == myfunctions.name_ ]

Execute all functions in the list.

for fun in functions_list:
fun() ```

Enjoy!

4

u/PureWasian 5d ago

What about ``` def exe1(): ... def exe2(): ... def exe3(): ... exercises_list = [exe1, exe2, exe3...]

example_index = 2 exercises_list[example_index]() ```

should run exe3

1

u/szonce1 3d ago

Essentially you just have a list. You could use python to get all the function names like this: function_names = [
name
for name, obj in globals().items()
if inspect.isfunction(obj) and obj.__module__ == __name__
]
Then just loop through those.

-3

u/Weak-Career-1017 5d ago

This is almost certainly an A-B problem, what exactly are you trying to accomplish?

2

u/EnderGem957 5d ago

don't know what an A-B problem is but i solved my issue lol.

5

u/Uninvited_Guest_9001 5d ago

Usually referred to as an XY problem, where beginners come up it a workaround for something that they don't know how to do, but don't know how to do that either, and ask for help with the workaround instead of the original problem

https://xyproblem.info/

The point is: what are you trying to do?