2009-05-08 10 views
5

क्यों करीबी कार्यों की सूची बनाने का यह प्रयास काम नहीं करता है?इस पायथन समारोह में लैम्ब्डा अभिव्यक्ति के साथ क्या चल रहा है?

def p(x, num): 
    print x, num 

def test(): 
    a = [] 
    for i in range(10): 
     a.append(lambda x: p (i, x)) 
    return a 

>>> myList = test() 
>>> test[0]('test') 
9 test 
>>> test[5]('test') 
9 test 
>>> test[9]('test') 
9 test 

यहां क्या हो रहा है?

एक समारोह वास्तव में मैं ऊपर समारोह करने की उम्मीद क्या करता है वह यह है कि:

import functools 
def test2(): 
    a = [] 
    for i in range (10): 
     a.append(functools.partial(p, i)) 
    return a 


>>> a[0]('test') 
0 test 
>>> a[5]('test') 
5 test 
>>> a[9]('test') 
9 test 
+0

चूंकि आपके पास एक समाधान है जो functools.partial का उपयोग करता है, सवाल क्या है? –

+2

सवाल यह है कि पहली विधि क्यों काम नहीं करती है? – David

उत्तर

12

अजगर में, लूप और शाखाओं में बनाए गए चर scoped नहीं कर रहे हैं। lambda के साथ आपके द्वारा बनाए गए सभी फ़ंक्शंस में i वैरिएबल का संदर्भ है, जो लूप के अंतिम पुनरावृत्ति पर 9 पर सेट है।

समाधान एक फ़ंक्शन बनाने के लिए है जो फ़ंक्शन देता है, इस प्रकार इटरेटर चर को स्कॉप करता है। यही कारण है कि functools.partial() दृष्टिकोण काम करता है। उदाहरण के लिए:

+0

समझ गया। बहुत बहुत धन्यवाद! – David

0

मैंने एक समान प्रश्न पूछा, और दो जवाब मिल गए। मूल रूप से स्वीकार्य उत्तर के समान ही, और दूसरा जो कम स्पष्ट है लेकिन थोड़ा अधिक संक्षिप्त है।

Dynamically creating a menu in Tkinter. (lambda expressions?)

+0

जिसमें लम्बा x = x: ... हैक शामिल है (और मैं अंततः समझता हूं)। –

1

वैसे आप भी आलसी के लिए एक बाहरी लैम्ब्डा को मैं बाध्य कर सकते हैं।

def p(x, num): 
    print x, num 

def test(): 
    a = [] 
    for i in range(10): 
     a.append((lambda i :lambda x: p (i, x))(i)) 
    return a 
1

मैं हमेशा उलझन में था कि यह क्यों काम नहीं करता है। स्पष्टीकरण के लिए धन्यवाद, 'a paid nerd'।

for i in range(10): 
    a.append(lambda num, val_i=i: p (val_i, num)) 

नोट lambda कि जब अभी भी प्रभावी ढंग से lambda 1 चर के एक समारोह बनाने पाश दौरान i की तात्कालिक मूल्य पर कब्जा करने के लिए सक्षम बनाता है के val_i=i डिफ़ॉल्ट तर्क: मैं व्यक्तिगत रूप से इस समाधान पसंद करते हैं। (BTW:। p की परिभाषा से मेल करने के num में अपने x परिवर्तित) मुझे पसंद है यह बेहतर है क्योंकि:

  1. यह बहुत मूल विचार के करीब है और एक नया नाम दिया है समारोह, ठीक करने के उद्देश्य को परिभाषित करने के लिए टाल एक लैम्ब्डा ...
  2. functools
  3. आयात करने से बचा जाता है और imbricating lambdas से बचा जाता है ...

बस एक खोज किया था और एक ही समस्या वहाँ के लिए और अधिक विस्तृत व्याख्या पाया: Scope of python lambda functions and their parameters

+0

नामित तर्क यह है कि यह क्यों काम करता है और क्यों आपका मूल नहीं था। पाइथन में बंद होने की मेरी खोज यहां दी गई है: https://gist.github.com/maxcountryman/5035489 – maxcountryman

संबंधित मुद्दे