For the sake of illustration let us take a very simple example. Supposedly, we want to evaluate the sum of every Nth element in the list. We can try to solve the problem by creating a list of lambda functions and then applying it to the list:
functions_list = []
N = 3
for i in xrange(N):
functions_list.append(lambda x: sum([my_list[j*N + i]
for j in xrange(len(my_list)/N)]))
If we test our functions now, we will get a wrong results:
>>> my_list = range(12)
>>> [f(my_list) for f in functions_list]
[26, 26, 26]
The problem is that interpreter will look for the value of
i in the scope, in our case it will find equal to 2 and use for every function in the list.Using
eval() function allows to "embed" the value of i in the functions body at the moment of its creation:functions_list = []
for i in xrange(N):
f_str = 'lambda x: sum([my_list[j*%i + %i] ' + \
'for j in xrange(len(my_list)/%i)])' %( N, i, N)
functions_list.append(eval(f_str))
And this will lead to the correct solution.
>>> [f(my_list) for f in functions_list]
[18, 22, 26]