Генерация списка функций в Python - PullRequest
5 голосов
/ 13 декабря 2010

У меня есть следующий код Python, который генерирует список анонимных функций:

basis = [ (lambda x: n*x) for n in [0, 1, 2] ]     
print basis[0](1)

Я бы ожидал, что он будет эквивалентен

basis = [ (lambda x: 0*x), (lambda x: 1*x), (lambda x: 2*x) ]
print basis[0](1)

Однако, тогда как второй фрагментвыводит 0, что я и ожидал, первые печатает 2. Что не так с первым фрагментом кода, и почему он не работает так, как ожидалось?

Ответы [ 4 ]

8 голосов
/ 13 декабря 2010

Вы можете использовать параметр по умолчанию для создания замыкания на n

>>> basis = [ (lambda x,n=n: n*x) for n in [0, 1, 2] ]     
>>> print basis[0](1)
0
3 голосов
/ 13 декабря 2010

Потому что это «передать по имени».

То есть, когда lambda запускается, он выполняет n*x: x привязан к 1 (это параметр), n ищется в среде (это * 1008) * сейчас 2 ). Итак, результат 2.

2 голосов
/ 13 декабря 2010

Проблема в том, что в первом примере каждая лямбда привязана к одному и тому же n - другими словами, она захватывает переменную, а не ее значение.Поскольку n имеет значение 2 в конце цикла, каждая лямбда использует значение 2 для n.

Видимо, вы можете использовать параметры по умолчанию для решения этой проблемы:

basis = [ (lambda x,n=n: n*x) for n in [0, 1, 2] ]
print basis[0](1) 

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

0 голосов
/ 22 февраля 2016

Я хочу помочь с пониманием комментария от Карла Кнехта (13 декабря 10 в 7:32). В следующем коде показано, как при использовании генератора исходное лямбда-определение дает ожидаемый результат, но не использует список или кортеж:

>>> #GENERATOR
... basis = ( (lambda x: n*x) for n in [0, 1, 2] )  
>>> print(type(basis))
<type 'generator'>
>>> basis = ( (lambda x: n*x) for n in [0, 1, 2] ) 
>>> print([x(3) for x in basis])
[0, 3, 6]
>>> #TUPLE
... basis = tuple( (lambda x: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'tuple'>
>>> print([x(3) for x in basis])
[6, 6, 6]
>>> #LIST
... basis = list( (lambda x: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'list'>
>>> print([x(3) for x in basis])
[6, 6, 6]
>>> #CORRECTED LIST
... basis = list( (lambda x, n=n: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'list'>
>>> print([x(3) for x in basis])
[0, 3, 6]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...