दिलचस्प पोस्ट
विज़ुअल स्टूडियो 2012,2013 या 2015 लाइसेंस कुंजी को कैसे परिवर्तित करें? आर 7 के साथ Win7 64 बिट पर आरजावा पैकेज का उपयोग करना उपयोगकर्ता के लोकेल प्रारूप और समय ऑफसेट में प्रदर्शित दिनांक / समय javafx 8 संगतता मुद्दे – FXML स्थिर फ़ील्ड कमांड प्रॉम्प्ट कमांड चलाएं Django Rest Framework serializer में कस्टम त्रुटि संदेश Android पर SQLite डेटाबेस का अधिकतम आकार क्या है? जावास्क्रिप्ट / jQuery के साथ मक्खी पर सीएसएस वर्ग संपत्ति मूल्यों को संशोधित करना जावास्क्रिप्ट गतिशील रूप से स्ट्रिंग से वस्तु विधि का आह्वान करता है मैं VBA में FileSystemObject का उपयोग कैसे करूं? चेक किए गए बनाम अनचेक किए गए अपवाद फ़ायरबसे ऑफ़लाइन क्षमताएं और ऐडलिस्टनरफोरसिंलिंगवैल्यूइवेंट Google पत्रक में अपलोड किए गए CSV या XLS फ़ाइल से डेटा को स्वचालित रूप से आयात कैसे करें JSF क्रॉस फील्ड प्रमाणीकरण का समर्थन नहीं करता है, क्या कोई वैकल्पिक उपाय है? जब सदिश बढ़ता है तो चाल शब्दों को कैसे लागू किया जाए?

पायथन लैम्ब्डा समापन स्कोपिंग

मैं फ़ंक्शन के हस्ताक्षर से एक चर को समाप्त करने के लिए क्लोजर का उपयोग करने की कोशिश कर रहा हूं (यह मान है कि मूल्यों को स्टोर करने वाले शब्दकोश में मापदंडों की एक बड़ी संख्या को नियंत्रित करने के लिए इंटरफ़ेस के लिए क्यूटी सिग्नल को जोड़ने के लिए आवश्यक सभी फ़ंक्शन लिखना)

मुझे समझ में नहीं आ रहा है कि lambda का उपयोग करने का मामला दूसरे फ़ंक्शन में लिपटा क्यों नहीं है, सभी मामलों के लिए अंतिम नाम लौटाता है।

 names = ['a','b','c'] def test_fun(name,x): print name,x def gen_clousure(name): return lambda x: test_fun(name,x) funcs1 = [gen_clousure(n) for n in names] funcs2 = [lambda x: test_fun(n,x) for n in names] # this is what I want In [88]: for f in funcs1: ....: f(1) a 1 b 1 c 1 # I do not understand why I get this In [89]: for f in funcs2: ....: f(1) c 1 c 1 c 1 

वेब के समाधान से एकत्रित समाधान "पायथन लैम्ब्डा समापन स्कोपिंग"

इसका कारण यह है कि क्लोजर (लैम्ब्दास या अन्यथा) नामों पर बंद, मान नहीं है जब आप lambda x: test_fun(n, x) परिभाषित करते हैं lambda x: test_fun(n, x) , n का मूल्यांकन नहीं किया जाता है, क्योंकि यह फ़ंक्शन के अंदर है। इसका मूल्यांकन तब किया जाता है जब फ़ंक्शन कहा जाता है , उस समय उस मूल्य का जो लूप से अंतिम मान होता है।

आप शुरू में कहते हैं कि आप "फ़ंक्शन हस्ताक्षर से एक चर को समाप्त करने के लिए बंद करने का उपयोग करना चाहते हैं", लेकिन यह वास्तव में इस तरह से काम नहीं करता है। (नीचे देखें, यद्यपि, एक तरीका है जो आपको संतुष्ट कर सकता है, "आप" से क्या मतलब है, इसके आधार पर)। फ़ंक्शन के परिभाषित होने पर फ़ंक्शन बॉडी के अंदर वेरिएबल का मूल्यांकन नहीं किया जाएगा। फ़ंक्शन को फ़ंक्शन-डेफिनिशन समय पर मौजूद के रूप में चर के "स्नैपशॉट" लेने के लिए, आपको चर को एक तर्क के रूप में पास करना होगा। ऐसा करने का सामान्य तरीका फ़ंक्शन को तर्क देना है जिसका डिफ़ॉल्ट मान बाह्य क्षेत्र से चर है। इन दो उदाहरणों के बीच के अंतर को देखें:

 >>> stuff = [lambda x: n+x for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 4 4 4 >>> stuff = [lambda x, n=n: n+x for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 2 3 4 

दूसरे उदाहरण में, n को उस फ़ंक्शन के n के मौजूदा मान में "लॉक इन" फ़ंक्शन के तर्क के रूप में पास करना। आपको इस तरह कुछ करना होगा यदि आप मूल्य में इस तरह से लॉक करना चाहते हैं। (यदि यह इस तरह से काम नहीं करता है, तो वैश्विक वैरिएबल जैसी चीजें बिल्कुल काम नहीं करेंगी, यह जरूरी है कि उपयोग के समय मुफ्त चर देखा जाए।)

ध्यान दें कि इस व्यवहार के बारे में कुछ भी लैम्ब्दास के लिए विशिष्ट नहीं है यदि आप किसी फ़ंक्शन को परिभाषित करने के लिए def का उपयोग करते हैं, तो समान स्कोपिंग नियम लागू हो सकते हैं, जो कि संलग्न आवृत्ति से चर को संदर्भित करता है।

अगर आप वास्तव में चाहते हैं, तो आप अपने लौटे फ़ंक्शन पर अतिरिक्त तर्क जोड़ने से बच सकते हैं, लेकिन ऐसा करने के लिए आपको उस फ़ंक्शन को एक और समारोह में लपेट करना होगा, जैसे:

 >>> def makeFunc(n): ... return lambda x: x+n >>> stuff = [makeFunc(n) for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 2 3 4 

यहां, जब भी कहा जाता है, आंतरिक लैम्ब्डा अभी भी n के मान को देखता है। लेकिन इसका अर्थ यह है कि वैश्विक वैरिएबल नहीं रह गया है, बल्कि एक स्थानीय वैरिएबल संलग्न समारोह makeFunc अंदर है। इस लोकल वैरिएबल का एक नया मान हर बार makeFunc जाता है, makeFunc को बुलाया जाता है, और लौटा लैम्ब्डा एक क्लोजर बनाता है जो कि लोकल वैरिएबल वैल्यू बचाता है जो कि makeFunc उस makeFunc लिए प्रभावी था। इस प्रकार लूप में बनाया गया प्रत्येक फ़ंक्शन का नाम "निजी" चर है जिसे x कहते हैं। (इस सरल मामले के लिए, यह बाहरी कार्य के लिए लैम्ब्डा का प्रयोग करके भी किया जा सकता है — stuff = [(lambda n: lambda x: x+n)(n) for n in [1, 2, 3]] – – लेकिन यह कम पठनीय है।)

ध्यान दें कि आपको अभी भी अपने n को एक तर्क के रूप में पारित करना होगा, ऐसा सिर्फ इतना ही है कि यह इस तरह से कर रहा है, आप इसे उसी कार्य के लिए एक तर्क के रूप में नहीं देते हैं जो कि stuff सूची में जाने वाली हवाएं; इसके बजाए आप इसे एक सहायक फ़ंक्शन के लिए एक तर्क के रूप में पास करते हैं जो आपको उस कार्य को बनाता है जिसे आप stuff में डालना चाहते हैं। इस दो-फ़ंक्शन दृष्टिकोण का उपयोग करने का लाभ यह है कि लौटा हुआ कार्य "स्वच्छ" है और इसमें अतिरिक्त तर्क नहीं है; यह उपयोगी हो सकता है यदि आप फ़ंक्शंस लपेटते थे जो कई तर्कों को स्वीकार करते थे, तो उस स्थिति में यह याद रखना भ्रामक हो सकता है कि सूची में n तर्क कहाँ था। यह नुकसान यह है कि, ऐसा करने से, कार्य करने की प्रक्रिया अधिक जटिल होती है, क्योंकि आपको एक और संलग्न समारोह की आवश्यकता होती है।

इसका नतीजा यह है कि एक ट्रेडऑफ है: आप फ़ंक्शन-सृजन प्रक्रिया को सरल बना सकते हैं (यानी, दो नेस्टेड फ़ंक्शन के लिए कोई ज़रूरत नहीं), लेकिन फिर आपको परिणामी फ़ंक्शन को थोड़ा और अधिक जटिल बनाना होगा (अर्थात, इसमें यह अतिरिक्त n=n तर्क)। या आप फ़ंक्शन को सरल बना सकते हैं (यानी, इसमें कोई n= n तर्क नहीं है), लेकिन फिर आपको फ़ंक्शन-क्रिएशन प्रक्रिया को और अधिक जटिल बनाना चाहिए (यानी, तंत्र को कार्यान्वित करने के लिए आपको दो नेस्टेड फ़ंक्शन की आवश्यकता है)।