2013-06-26 5 views
1

나는 내 머리에 상처를주는 것을 발견했습니다. 예상대로 반환 다음파이썬 값 대 참조

fs = [] 
for i in range(3): 
    fs.append(lambda : normal(i, .001)) 
    print mean([fs[-1]() for j in range(1000)]) 
print [mean([fs[i]() for j in range(1000)]) for i in range(3)] 

, 예를 들어,

-1.38651717873e-05                             | 
1.00003545604                               | 
1.99999343229                               | 
[2.0530899455777235e-05, 0.99995283932453838, 2.0000045292311737] 

을 고려하십시오. 이제 약간

fs = [] 
for i in range(3): 
    mu = i 
    fs.append(lambda : normal(mu, .001)) 
    print mean([fs[-1]() for j in range(1000)]) 
print [mean([fs[i]() for j in range(1000)]) for i in range(3)] 

물건을 수정하고 우리는 루프 외부 사람의 각

5.56620751611e-06                              | 
0.999999076252                              | 
1.99995161119                               | 
[2.0000016397219098, 1.9999853403014964, 2.0000209870831158] 

즉 2를 얻을. 내 머리를 kerploding 후, 나는 참조/파이썬에서 범위가 악한 것을 기억하고 대답은 mu가 정상으로 전달된다는 것이 가치보다는 참조에 의해 저장된다는 것입니다 (mu가 일반 언어로 범위를 지정해야 함에도 불구하고) . 그게 무슨 일 이니? 어떻게 미래의 코딩에서 비슷한 광기를 피할 수 있습니까?

+1

관련 : HTTP :/함수 정의시에 mu의 값을 수정하려면, 너무 같은 기본 인자 값을 사용 /stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python –

답변

1

파이썬의 클로저는 이름으로되어 있습니다 (기술적으로는 아니지만 그런 식으로 생각할 수 있습니다). 따라서 모든 람다는 mu에 대해 2의 값을 가지므로 루프의 mu에 마지막 값이 지정됩니다.

lambda mu=mu: normal(mu, .001) 

(범위 지정 규칙 정말이와 아무 상관이 없습니다.)

+0

잘 작동합니다. 나를 "클로저"에서 읽을 수있는 곳으로 안내 할 수 있습니까? 나는 용어에 익숙하지 않다 – andyInCambridge

+0

http://www.shutupandship.com/2012/01/python-closures-explained.html – Elazar

+0

http://en.wikipedia.org/wiki/Closure_ (computerer_science) – Elazar