2015-03-25 4 views
7

Я изо всех сил пытаюсь сделать работу лямбда. Здесь приведен пример кода, но он хорошо показывает мою проблему.Почему мои лямбды не работают?

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 


print lambdas[0](1) 
print lambdas[2](1) 

Это дает мне 16, но я ожидаю, что у меня будет другое значение для разных лямбда. Почему происходит!

+0

«Scoping in Python лексический. Закрытие всегда будет помнить имя и область действия переменной, а не объект, на который она указывает». http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python. Ваша лямбда фиксирует имя 'i', а не * значение объекта *, на которое ссылается' i'. – Shashank

ответ

9

В этом коде:

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 

Значение i определяется, когда функция запустить , Значение i, когда функция определена, потеряна.

Используйте вместо этого:

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x, i=i : i*i*x) 

print lambdas[0](1) 
print lambdas[2](1) 

Это дает:

0 
4 

Это работает, потому что, как частный случай, аргументы по умолчанию для функции, как и в i=i выше, связываются сразу.

+0

Объяснение, почему это не сработало изначально, сделало бы это отличным ответом. Но мне действительно нравится привязка моментального аргумента по умолчанию. – Serdalis

+1

@Serdalis Хорошая идея. Пояснение добавлено. – John1024

6

i является 4, когда ваша петля заканчивается так, что i составляет 4 на каждые lambda.

Если вы печатаете i вне цикла вы увидите, что это 4:

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 

print(i) 
4 

Вы используете переменную, которая в настоящее время обновляется в течение всего цикла, если вы звоните лямбда внутри цикла вы получите то, что вы ожидали.

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 
    print(lambda x: i * i * x)(1) 
0 
1 
4 
9 
16 

Поведение можно было бы ожидать, i просто переменная, как и любой другой.

На стороне записки вы можете использовать список Комп, чтобы создать свой список:

lambdas = [lambda x,i=i: i * i * x for i in xrange(5)] 
Смежные вопросы