[PYTHON] 외부 변수에 액세스하는 람다 함수 [duplicate]
PYTHON외부 변수에 액세스하는 람다 함수 [duplicate]
익명의 함수로 놀고 싶었 기 때문에 간단한 프라임 파인더를 만들기로 결정했습니다. 여기있어:
tests = []
end = int(1e2)
i = 3
while i <= end:
a = map(lambda f:f(i),tests)
if True not in a:
tests.append(lambda x:x%i==0)
print i
print tests
print "Test: "+str(i)
print str(a)
i+=2
그러나 내가 찾은 것은 람다 x의 i : x % i == 0이 매번 액세스되는 반면, 나는 그것이 문자 그대로의 숫자가되기를 원한다. 어떻게하면 λ x : x % 3 == 0이 될 수 있습니까?
해결법
-
==============================
1.당신은 람다를 만들 때 나는 "포획"할 수 있습니다.
당신은 람다를 만들 때 나는 "포획"할 수 있습니다.
lambda x, i=i: x%i==0
이것은 람다의 컨텍스트에서 내가 생성되었을 때의 것과 동일하게 설정합니다. 당신은 또한 lambda x, n = i : x % n == 0이라고 말할 수 있습니다. 원한다면, 정확히 포착되지는 않지만, 필요한 것을 얻을 수 있습니다.
당신이 본 것처럼 이것이 없다면, 그것은 둘러싼 범위에서 나는 찾을 것입니다.
정의 된 함수를 사용하는 다음과 유사한 조회 문제입니다.
i = "original" def print_i1(): print(i) # prints "changed" when called below def print_i2(s=i): #default set at function creation, not call print(s) # prints "original" when called below i = "changed" print_i1() print_i2()
-
==============================
2.문제는 테스트에서 각 함수가 변수 i를 참조한다는 것입니다.
문제는 테스트에서 각 함수가 변수 i를 참조한다는 것입니다.
더 일반적으로 함수 내부에서이를 수행합니다.이 경우에는 클로저에 저장되는 정의 할 수있는 범위 변수 i가 있습니다. 이러한 Nasty Closure에서 자세히 설명합니다.
하지만 여기에서는 더 간단합니다. 저는 전역 변수이므로 닫힘이 없습니다. 함수는 실행할 때 i를 전역 변수로 찾기 위해 컴파일됩니다. i가 변경 되었기 때문에 함수가 실행될 때 변경된 값을 볼 수 있습니다. 그처럼 간단합니다.
이것 (클로저와 전역 변수 모두에서 작동)을 둘러싼 전통적인 방법은 실제로 해킹이 아니더라도 "기본 값 해킹"으로 잘 알려져 있습니다. (FAQ의 설명을 참조하십시오.) Ryan Haining의 대답은이 작업을 수행하는 방법을 설명합니다.
lambda x, i=i: x%i==0
이렇게하면 i라는 매개 변수가 만들어지며,이 매개 변수의 기본값은 함수를 만들 때의 값과 같습니다. 그런 다음 함수 내부에서 매개 변수 i에 액세스하면 해당 값을 얻습니다.
JavaScript와 같은 언어를 사용하는 경우 더 익숙해 보일 수있는 다른 방법은 함수 작성 함수를 작성하고 user2864740의 대답과 같이 i의 값을 해당 함수 작성 함수의 인수로 전달하는 것입니다 :
(lambda i: lambda x: x%i)(i)
이것은 여분의 매개 변수 (누군가가 실수로 인수를 전달할 수 있음)를 사용하여 함수의 서명을 "오염"시키는 것을 피하지만 정당한 이유없이 함수를 작성하고 호출하는 대가를 치러야합니다.
세 번째 방법은 partial을 사용하는 것입니다. 래퍼 함수를 정의하는 대신에 partial을 사용하여 람다 (lambda)가 더 깔끔해질 수 있으므로 함수를 부분적으로 적용하는 것이 전부입니다.
불행히도이 경우 함수는 연산자 안에 숨겨져 있으며이를 노출하는 operator.mod 함수는 키워드 인수를 사용하지 않으므로 두 번째 피연산자를 유용하게 사용할 수 없습니다. 그래서,이 경우에는 나쁜 해결책입니다. 정말로 원한다면, 더 좋고 부분적으로 작동하는 래퍼를 작성할 수 있습니다.
def opmod(a, b): return a % b partial(operator.mod, b=i)
이 경우 다른 솔루션을 사용하는 것이 나을 것이라고 생각합니다. 적절한 경우에 대비하여 머리에 보관하십시오.
-
==============================
3.람다를 반환하는 새 함수를 만듭니다. 그런 다음 그것을 인수로 전달하십시오. 이렇게하면 새 바인딩 범위가 만들어집니다.
람다를 반환하는 새 함수를 만듭니다. 그런 다음 그것을 인수로 전달하십시오. 이렇게하면 새 바인딩 범위가 만들어집니다.
def make_test (i): # this i refers to the parameter (which evaluates to the /value/ passed) return lambda x: x%i==0 # .. # the /value/ resulting from evaluating the variable is passed tests.append(make_test(i))
from https://stackoverflow.com/questions/21053988/lambda-function-acessing-outside-variable by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 헤 루쿠 산발적 인 높은 응답 시간 (0) | 2018.11.02 |
---|---|
[PYTHON] Python : PIL은 단일 RGBA 색상을 대체합니다. (0) | 2018.11.02 |
[PYTHON] 파이썬 - 튜플 목록을 문자열로 변환 (0) | 2018.11.02 |
[PYTHON] subplots의 파이썬 xticks (0) | 2018.11.02 |
[PYTHON] PyInstaller를 사용할 때 명명 된 모듈이 없습니다. (0) | 2018.11.02 |