Functions in Lists Possible?

Hi all.

I just have a random question about lists in Python: can you call or define functions inside of lists like you can in JavaScript?

An example of this in JavaScript is:

const arrOfFunctions = [...Array(5).keys()].map(i => console.log(`This is hi number ${i}!`));

Each element is an anonymous function (in this example) that prints a message to the console that contains the iteration. The original array is an array of numbers from 0 to 4.

JS doesn’t do this either? You created an array, on this array you call the .map() method, the .map() method takes a callback function as argument.

but i am also a bit confused by your code, and this is why:


const arrOfFunctions = [...Array(5).keys()].map(i => console.log(`This is hi number ${i}!`));

console.log(arrOfFunctions);

the array now has only undefined values. Don’t forgot that map creates a new array. If you only want to log, .forEach would be a better choice

in python, i would do this very differently, but it depends on what you want to achieve

this is possible:

for i in range(5):
   print("This is hi number {}".format(i))

lists can refer to values
functions are values

calling a function is not a value, it is an action
defining a function is not a value, it is an action

a list literal includes comma-separated expressions, if you have an expression then you can include it in a list literal

a lambda expression is an expression
a call expression is an expression

an expression evaluates to a value

Hi,

Sorry for not being more specific. I guess I could have returned something in the map I wrote above and it was a poor example.

I was primarily thinking of the case of Promise.all in JavaScript where you want to do a bunch of asynchronous tasks that might use similar functions that themselves return Promises. You can do something if there’s either a successful or unsuccessful outcome of all of the resolved/rejected Promises. You provide an array of the function calls and then can do stuff depending on the outcome of all of the Promises returned by these functions.

I will refrain from showing a code example for the Promise.all example.

However, here is a simpler example:


function addOne(num) {

  return num + 1;

}

const arr = [addOne(0), addOne(2), addOne(99)];

console.log(arr);

>>> [1, 3, 100]

You can call your functions directly from inside the array even though what is ultimately stored are numbers in the example above. That’s my question: can you call functions from inside an array in Python?

an array of function calls is not a thing, this does not make sense
you can either supply an array of functions, or an array of results from having called functions, both of which is the same thing, an array of values, or simply an array

Hi ionatan,

Thank you. That’s the kind of answer I was looking for. In JS they’re treated like values. Since JS is what I know best and I’m here to learn Python, that’s why I asked the question in reference to JS.

Thank you again!

What you’re doing here:

const arr = [addOne(0), addOne(2), addOne(99)];

Is just:

const arr = [1, 3, 100];

there are no functions there.

What you would need to do instead is:

const arr = [addOne, addOne, addOne];

Hi ionatan,

Can I do the Python equivalent of calling functions inside the array? You seemed to imply that one can’t.

Btw, you can totally put a function reference inside an array in JS. It works and doesn’t throw any error :wink: If you do a console log on an array containing function references, it prints the functions.

It doesn’t make sense. You are not doing this in javascript either. You’re mixing up nouns and verbs.

What you are putting in your arrays in javascript is the result of calling your function, not the function.

So what is the result of those functions? Presumably you are talking about specific functions that return promises. So you do not have an array of functions, you have an array of promises.

Perhaps you then create another promise that resolves once any of the promises in the array resolve, or perhaps all, and then you can wait on a single promise instead of writing code to wait for each one.

Well, I got off my lazy butt and tested it in repl.it’s Python scripts.


def am_I_called():

  return True

my_list = [am_I_called()]

print(my_list)

>>> [True]

So I guess I just answered my own question :stuck_out_tongue:

Thanks for your time guys!

You’ll get the same outcome in javascript:

const am_I_called = () => true
const my_list = [am_I_called()]
console.log(my_list)

> [ true ]

Do you see the problem?

You’re not putting a function in the list. You are not testing the thing that you are talking about.

You’re just putting the value true, absolutely no fancy function-related things happening.

mylist.push(true)

That should make sense. If you put true in a list, you have true in a list.
And, if you put a function in a list, you have a function in a list.

But they’re not different cases, both cases are:
If you put a value in a list, you have a value in a list.

Defining or declaring a function:


// JS

function myFunction() {

// myCode

}

# Python

def my_function():

# my_code

Calling a function:


// JS

myFunction();

# Python

my_function();

An array or list with one function call:


// JS

const arrOfMyFunction = [myFunction()];

console.log(arrOfMyFunction);

>>> prints whatever results from code of myFunction wrapped inside an array

# Python

list_of_my_function = [my_function()]

print(list_of_my_function)

>>> prints whatever results from code of my_function wrapped inside a list

An array or list of function references or pointers if you prefer… in JS they’re known as references:


// JS

const arrOfReferences = [myFunction];

console.log(arrOfReferences);

>>> prints [[Function: myFunction]]

# Python

arr_of_references = [my_function]

>>> prints [<function my_function at 0x7fe96c274200>]

Those are the terms I am using.

You can even do the following in JS:


const arr3 = [function sayHi () { console.log("Hi!") }];

console.log(arr3);

In the above I just put a function directly inside the array. It returns [[Function: sayHi]]. It looks like I can’t do the same in Python but putting in a pointer to the function works.

My original question was about whether we can have a list of function calls in Python. Some languages do not allow you to do that.

Anyway, I answered my own question and maybe this will be helpful to someone else wondering the same thing. Who knows?

You can do exactly that in python.

arr3 = [lambda: print("Hi!")]
print(arr3)

Similarly you can define f and use the variable instead:

def f():
    print("Hi!")

print([f])

Like I said, a function is a value, and a list can refer to values, therefore you can put functions in lists.

But you were not putting functions in your list, so you saw no function in your list.
You put True in your list. And javascript behaves exactly the same way.

Neither language has access to pointers.

You were not doing this:

arr3 = [lambda: print("Hi!")]
print(arr3)

You were doing this:

arr3 = [(lambda: print("Hi!"))()]
print(arr3)

Which doesn’t put a function in the list. That calls the function, and puts the result of the function in a list. The function has already happened. You called it.

Similarly, if you write this:

[1 + 1]

The value that you are putting in that list is not lambda: 1+1, it is 2

Promises introduce another indirection.

The result of calling a function that returns a promise is, well, a promise.

You would first call the function to get the promise, then wait on the promise.

You can do this in python too (this is true of most if not all things javascript does, other than the ability to run in a browser)

async def f():
    return 5

print(
    [f()]
)
[<coroutine object f at 0x7fa375656a40>]

This time, f WAS called, and 5 still isn’t in the list. What’s in the list is a promise, something waiting to finish.

To get the value out, wait on it:

import asyncio

async def f():
    return 5

promise = f()

async def main():
    actual_result = await promise
    print(actual_result)

asyncio.run(main())
5

the equivalent javascript is nearly identical:

async function f () {
  return 5
}

async function main () {
  actual_result = await promise
  console.log(actual_result)
}

const promise = f()
main()
1 Like

Uh oh, you’ve created a bunch more rabbit holes for me to go down :stuck_out_tongue:

If I’m understanding you, it looks like Python:

  • has no pointers
  • has IIFE’s
  • has async/await

I’m still on the list classes in the Python 3 course. Knowing about async functions will be helpful since I will be starting a new job that requires Flask.

Thank you very much for your time. I learned a lot!

neither does javascript

nothing stopping you from calling a function without naming it, this isn’t a language feature, it’s just an idiom
What you probably mean is functions as expressions, aka lambda aka anonymous function.
But, this is not significant, it’s cosmetic.

yes, but this is not the default execution model, unlike nodejs

Hi, @velio, and welcome to the Codecademy Forums!

Yes. Here’s an example wherein the anonymous functions execute, but are not saved:

[(lambda x: print("This is number {:d}!".format(x)))(num) for num in range(7)]

Output:

This is number 0!
This is number 1!
This is number 2!
This is number 3!
This is number 4!
This is number 5!
This is number 6!

I’d really rather pick it apart into fundamental components instead of talking about special cases (it’s not special)

So, nothing can be defined inside a list. Lists are for referring to values, not for defining things

If you have a value, you can put it in a list.

And then, forget about list, and look at the value instead, so, can you define a function? Well, yes.

No?


Or, if talking about syntax, then, what can go inside a list literal? Expressions.
Got an expression? You can put it in a list literal. No exception.

1 Like