można uniknąć pętli pisząc coś takiego:
lis.append(lambda: 0)
lis.append(lambda: 1)
lis.append(lambda: 2)
zamiarem jest napisać lambda funkcje, które zwracają stałej liczby całkowite. Ale definiujesz i dołączasz funkcję zwracającą obiekt i
. Zatem 3 dołączone funkcje są takie same.
kodu bajtowego za funkcje stworzone powraca i
:
In [22]: import dis
In [25]: dis.dis(lis[0])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
In [26]: dis.dis(lis[1])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
In [27]: dis.dis(lis[2])
3 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
Wywołanie dowolnej z tych funkcji zwraca ostatnią wartość i
który jest 2
w kodzie próbki:
In [28]: lis[0]()
Out[28]: 2
jeśli usuniesz i
obiekt, pojawia się błąd:
In [29]: del i
In [30]: lis[0]()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-30-c9e334d64652> in <module>()
----> 1 lis[0]()
<ipython-input-18-15df6d11323a> in <lambda>()
1 lis = []
2 for i in range(3):
----> 3 lis.append(lambda: i)
NameError: global name 'i' is not defined
Rozwiązaniem może być, aby utrzymać przy użyciu pętli napisać kod ze stałych trzeba i faktycznie uruchomić ten kod:
In [31]: lis = []
...: for i in range(3):
...: exec 'lis.append(lambda: {})'.format(i)
...:
z następującymi wynikami:
In [44]: lis[0]()
Out[44]: 0
In [45]: lis[1]()
Out[45]: 1
In [46]: dis.dis(lis[0])
1 0 LOAD_CONST 1 (0)
3 RETURN_VALUE
In [47]: dis.dis(lis[1])
1 0 LOAD_CONST 1 (1)
3 RETURN_VALUE
To jest standardowe pytanie. na przykład http://stackoverflow.com/questions/1107210/python-lambda-problems, http://stackoverflow.com/questions/1924214/python-lambdas-and-scoping. Wiele, * wiele * więcej. –
powiązane: [Dlaczego wyniki map() i rozumienia list są różne?] (Http://stackoverflow.com/questions/139819/why-results-of-map-and-list-comprehension-are-different) – jfs