Let’s start from the beginning. According to documentation:
Functions are first-class Objects.
That is, in Python the functions are "first-class citizens": they are treated as if they were "normal" values, can be placed in lists, assigned to a variable, passed as parameter to other functions, etc. On this subject, you can read more here, here and here.
Therefore, a function can be assigned to a variable:
def square(y):
return y ** 2
def cube(y):
return y ** 3
# atribui a função a uma variável
funcao = square
# como "funcao" aponta para "square", posso chamá-la normalmente
print(funcao(3)) # 9
# atribui outra função na mesma variável
funcao = cube
# agora "funcao" aponta para "cube"
print(funcao(3)) # 27
And I can also create a list of various functions, scroll through that list in one loop and call them all:
def square(y):
return y ** 2
def cube(y):
return y ** 3
# lista contendo as funções
funcs = [square, cube]
# para cada função da lista, chamá-la passando o número 3 como argumento
for funcao in funcs:
print(f'chamando {funcao.__name__}: {funcao(3)}')
The output of this code is:
chamando square: 9
chamando cube: 27
Now about the map
: all he does is apply a function to all the elements of an eternal. That is, if I do:
def dobro(n):
return n * 2
valores = [1, 2, 3]
for result in map(dobro, valores):
print(result)
This will print 2
, 4
and 6
, for map(dobro, valores)
apply the function dobro
to each of the elements on the list valores
. Essentially, this would be equivalent to:
for valor in valores:
print(dobro(valor))
But in your case the list has no values that are passed to a function. What it has are functions that will be called with a certain value. I mean, it would be like doing this:
# para cada função da lista "funcs", chamá-la passando o "3" como argumento
for funcao in funcs:
print(funcao(3))
And in this case, the equivalent using map
would have to be:
for result in map(lambda funcao: funcao(3), funcs):
print(result)
That is, the function that map
receives is a lambda
(that in the background is also a function), which takes as argument a function and the flame (passing, in this case, the number 3
as argument). That is, instead of myself calling the function directly within the loop, is the map
that the flame and returns the result (so within the for
I can already catch the direct result).
But in your case you’re not iterating for map
, and yes taking his result and passing to list
, which in turn creates a list containing all the results. That is, when you do:
valor = map(lambda funcao: funcao(3), funcs)
print(list(valor)) # [9, 27]
Would be equivalent to doing:
results = [] # cria uma lista vazia
# para cada resultado do map, adicioná-lo na lista
for result in map(lambda funcao: funcao(3), funcs):
results.append(result)
print(results) # [9, 27]
And finally, in your code all this is done inside a loop, iterating by list values [0, 1, 2, 3, 4]
. In the above examples I always passed the number 3
for the duties, but in its loop he does it for all values on the list.
That is, first he calls the functions to the 0
and print the list with the results, then do the same for the 1
, to the 2
etc..
And just for the record, another way to create this list of results would be to use a comprehensilist on:
for i in lista:
print([ funcao(i) for funcao in funcs ])