Python: цикл for перезаписывает лямбда-функцию, созданную в цикле - PullRequest
0 голосов
/ 02 ноября 2018

Я работаю с Python 2.7, и я наткнулся на эту проблему, и я даже не могу понять логику того, почему следующее не работает.

Мне нужно разместить другой набор данных, и я хочу сделать это динамически в цикле for. Вот MWE, который дублирует проблему:

import numpy as np
from scipy.optimize import curve_fit


def func_to_fit(x, a):
    return x ** a


x = np.arange(0, 10)
dummy_dataset = {1: x ** 2,
                 2: x ** 3}

param = {}
fitted_func = {}

print "First loop"
for i in [1, 2]:
    if i == 1:
        idx = "Ex"
    else:
        idx = "Ez"
    # store the results in different items in a dictionary to avoid the usual copying issues in Python
    param[idx] = curve_fit(func_to_fit, x, dummy_dataset[i])[0]  
    fitted_func[idx] = lambda x: func_to_fit(x, *param[idx])
    print idx, fitted_func[idx](x)
print param
print fitted_func

print "Ex", fitted_func["Ex"](x)
print "Ez", fitted_func["Ez"](x)

А на выходе

First loop
Ex [  0.   1.   4.   9.  16.  25.  36.  49.  64.  81.]
Ez [   0.    1.    8.   27.   64.  125.  216.  343.  512.  729.]
{'Ex': array([ 2.]), 'Ez': array([ 3.])}
{'Ex': <function <lambda> at 0x0000000015989EB8>, 'Ez': <function <lambda> at 0x0000000015989F98>}
Ex [   0.    1.    8.   27.   64.  125.  216.  343.  512.  729.]
Ez [   0.    1.    8.   27.   64.  125.  216.  343.  512.  729.]

Поведение перед печатью «Второй цикл» такое, как я ожидаю: вне цикла, где я выполняю подгонку, параметры, сохраненные в param , являются правильными («Ex "= 2 и" Ez "= 3), функции в fit_func хранятся в разных местах памяти, и когда я вызываю их в первом цикле, они дают правильные результаты, а именно fit_func [" Ex "] (x) = x ^ 2 и fit_func ["Ez"] (x) = x ^ 3.

Однако , если я вызываю каждую подобранную функцию отдельно, как я делаю с последними двумя строками кода, и я пытаюсь вычислить значения функций, у меня неправильный результат, то есть обе функции возврат х ^ 3.

Полагаю, это поведение в некоторой степени связано с тем, как Python обрабатывает память, и с каким-то условием гонки, то есть Python вычисляет каждый раз, когда лямбда-функция в fit_func [idx], и запоминает последний действительный результат (в этом случае подгонка для х ^ 3). Во всяком случае, я не совсем понимаю, в чем именно проблема и как ее преодолеть.

Надеюсь, мне удалось правильно проиллюстрировать проблему, кто-нибудь имеет представление о 1. Что вызывает эту проблему? 2. Как это побороть?

Большое спасибо!

...