पाइथन लैंबडास उपयोगी क्यों हैं? [बन्द है]


928

मैं पायथन लैम्ब्डा का पता लगाने की कोशिश कर रहा हूं। लैम्बडा उन "दिलचस्प" भाषा वस्तुओं में से एक है जिसे वास्तविक जीवन में भूल जाना चाहिए?

मुझे यकीन है कि कुछ किनारे मामले हैं जहां इसकी आवश्यकता हो सकती है, लेकिन इसकी अस्पष्टता को देखते हुए, इसे भविष्य के रिलीज में पुनर्परिभाषित किए जाने की संभावना है (इसकी विभिन्न परिभाषाओं के आधार पर मेरी धारणा) और कम कोडिंग स्पष्टता - यह होना चाहिए दूर रहे?

यह मुझे सी प्रकार के अतिप्रवाह (बफर ओवरफ्लो) की याद दिलाता है - शीर्ष चर की ओर इशारा करते हुए और अन्य क्षेत्र मूल्यों को सेट करने के लिए ओवरलोडिंग। ऐसा लगता है कि एक तरह का तकनीकी प्रदर्शन है, लेकिन रखरखाव कोडर दुःस्वप्न है।


261
+1 अच्छा प्रश्न - बुरी धारणाएँ (मेमने की अस्पष्टता) =) प्रोग्रामिंग तकनीकों का निर्णय नहीं होना चाहिए। उनका मूल्यांकन करें, और उन्हें अपने मानसिक टूलकिट में जोड़ें। यदि आप उन्हें पसंद नहीं करते हैं, तो उनका उपयोग न करें, और धार्मिक बने बिना तार्किक रूप से चर्चा करने के लिए तैयार रहें।
केवली

41
हास्केल नियम! लैम्ब्डा फ़ंक्शन आपको अभिव्यक्तता और अमूर्त शक्ति प्रदान करता है।
जोनाथन बारबेरो

11
@ JALP LISP का जिक्र तक नहीं ...
ApproachingDarknessFish

8
@ApproachingDarknessFish "आह, वह तुम्हारे पिता का कोपभाजन है। अधिक सभ्य उम्र से अधिक सभ्य हथियार।" - ओबी लिस्प केनोबी
फील्ड्स

जवाबों:


1008

क्या आप लंबोदर कार्यों के बारे में बात कर रहे हैं ? पसंद

lambda x: x**2 + 2*x - 5

वे चीजें वास्तव में काफी उपयोगी हैं। पायथन प्रोग्रामिंग की एक शैली का समर्थन करता है जिसे कार्यात्मक प्रोग्रामिंग कहा जाता है जहां आप सामान को करने के लिए अन्य कार्यों को पास कर सकते हैं। उदाहरण:

mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])

मूल सूची के उन तत्वों के mult3लिए सेट करता है [3, 6, 9], जो 3. के गुणक हैं। यह छोटा है (और, एक से बहस कर सकते हैं, स्पष्ट कर सकते हैं)

def filterfunc(x):
    return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])

बेशक, इस विशेष मामले में, आप एक सूची समझ के रूप में एक ही काम कर सकते हैं:

mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]

(या यहां तक ​​कि range(3,10,3)), लेकिन कई अन्य, अधिक परिष्कृत उपयोग के मामले हैं जहां आप सूची समझ का उपयोग नहीं कर सकते हैं और एक लैम्ब्डा फ़ंक्शन कुछ लिखने का सबसे छोटा तरीका हो सकता है।

  • दूसरे फ़ंक्शन से एक फ़ंक्शन वापस करना

    >>> def transform(n):
    ...     return lambda x: x + n
    ...
    >>> f = transform(3)
    >>> f(4)
    7
    

    यह अक्सर फ़ंक्शन रैपर बनाने के लिए उपयोग किया जाता है, जैसे कि पायथन के सज्जाकार।

  • के साथ एक चलने योग्य अनुक्रम के तत्वों का संयोजन reduce()

    >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])
    '1, 2, 3, 4, 5, 6, 7, 8, 9'
    
  • एक वैकल्पिक कुंजी द्वारा छंटनी

    >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
    [5, 4, 6, 3, 7, 2, 8, 1, 9]
    

मैं एक नियमित आधार पर लैम्ब्डा कार्यों का उपयोग करता हूं। मुझे उनकी आदत पड़ने में थोड़ा समय लगा, लेकिन आखिरकार मुझे समझ में आ गया कि वे भाषा का बहुत मूल्यवान हिस्सा हैं।


26
उदाहरणों से प्यार करो, समझने में बहुत आसान है। लेकिन कम किए गए हिस्से के लिए। अगर मुझे इस सुविधा को लागू करना है। मैं करता हूँ','.join(str(x) for x in [1,2,3,4,5,6,7,8,9])
et

3
BTW अगर आप इसे Python3 पर चलाते हैं, तो आपको वास्तविक मूल्यों को देखने के लिए फ़िल्टर परिणामों पर सूची को कॉल करने की आवश्यकता है, साथ ही आपको फंक्शंस से कम करने की आवश्यकता है
जेरार्ड

क्या हम ऊपर "कार्यात्मक प्रोग्रामिंग" की परिभाषा के बारे में निश्चित हैं? यह मेरे लिए थोड़ा भ्रमित करने वाला था।
22

3
मुझे लगता है कि मुख्य बिंदु यह है कि lambdaफ़ंक्शन अनाम हो सकते हैं (जैसा कि वे आपके सभी उदाहरणों में हैं)। यदि आप किसी lambdaभी चीज़ को फ़ंक्शन दे रहे हैं तो आप इसे गलत कर रहे हैं और defइसके बजाय का उपयोग करना चाहिए
क्रिस

1
@zgulser यह एक परिभाषा नहीं है, यह केवल एक ऐसी चीज़ के बारे में एक बयान है जिसे कार्यात्मक प्रोग्रामिंग आपको करने की अनुमति देता है।
डेविड जेड

377

lambdaकहने का सिर्फ एक फैंसी तरीका है function। इसके नाम के अलावा, इसके बारे में कुछ भी अस्पष्ट, डराना या बकवास नहीं है। आप निम्नलिखित लाइन पढ़ते हैं, की जगह lambdaसे functionआपके मन में:

>>> f = lambda x: x + 1
>>> f(3)
4

यह सिर्फ एक फ़ंक्शन को परिभाषित करता है x। कुछ अन्य भाषाएँ, जैसे R, स्पष्ट रूप से कहती हैं:

> f = function(x) { x + 1 }
> f(3)
4

आप समझ सकते हैं? यह प्रोग्रामिंग में सबसे प्राकृतिक चीजों में से एक है।


36
यह नॉन-प्रोग्रामिंग बैकग्राउंड (यानी: सटीक विज्ञान) से आने वालों के लिए एक शानदार विवरण है, जो lambda समझने में बहुत सरल है। धन्यवाद!
गेब्रियल

10
रेमंड हेटिंगर ने अपनी एक बातचीत में नाम पर अफसोस जताया और कहा कि 'लंबोदर' के बजाय इसे 'फंक्शन' का नाम देकर सभी भ्रमों से बचा जा सकता था। :-)
अंकुश

10
की जगह lambdaसे functionआपके मन में और जोड़ने के returnपिछले अभिव्यक्ति से पहले
सिपरियन Tomoiagă

4
@AaronMcMillin आज़माएं type(lambda x: 3)lambdaभाव और defकथन दोनों ही functionवस्तुओं को उत्पन्न करते हैं; यह केवल एक lambdaअभिव्यक्ति का वाक्यविन्यास है जो इसे उत्पन्न करने वाले उदाहरणों को सीमित करता है
Chepner

6
@AaronMcMillin आपको मेरी बात याद आ रही है। सिर्फ इसलिए कि आप प्रत्येक फ़ंक्शन को एक lambdaअभिव्यक्ति के साथ परिभाषित नहीं कर सकते हैं इसका मतलब यह नहीं है कि एक lambdaअभिव्यक्ति का परिणाम एक फ़ंक्शन नहीं है।
Chepner

107

दो-पंक्ति सारांश:

  1. क्लोजर : बहुत उपयोगी है। उन्हें जानें, उनका उपयोग करें, उन्हें प्यार करें।
  2. पायथन का lambdaकीवर्ड: अनावश्यक, कभी-कभी उपयोगी। यदि आप अपने आप को इसके साथ कुछ भी जटिल करते हुए पाते हैं, तो इसे दूर रखें और एक वास्तविक कार्य को परिभाषित करें।

72

एक लैम्ब्डा एक बहुत महत्वपूर्ण अमूर्त तंत्र का हिस्सा है जो उच्च क्रम के कार्यों से संबंधित है। इसके मूल्य की उचित समझ पाने के लिए , एबेल्सन और सुस्मान से उच्च गुणवत्ता वाले सबक देखें और किताब SICP पढ़ें

ये आधुनिक सॉफ्टवेयर व्यवसाय में प्रासंगिक मुद्दे हैं, और कभी अधिक लोकप्रिय हो रहे हैं।


1
अन्य भाषाओं (जैसे C #) में भी लैंबडा भाव लोकप्रिय हो रहे हैं। वे कहीं नहीं जा रहे हैं। बंद पर पढ़ना लैम्ब्डा को समझने के लिए एक उपयोगी अभ्यास होगा। क्लोजर jQuery जैसे चौखटे में बहुत सारे कोडिंग जादू संभव बनाते हैं।
डान एस्परज़ा

3
lambdaएस और प्रथम श्रेणी के कार्यों को भ्रमित न करें । पायथन में एक अत्यंत सीमित lambdaकथन है, लेकिन पूरी तरह से प्रथम श्रेणी के कार्य हैं। एकमात्र अंतर यह है कि आपको उन कार्यों का नाम देना होगा जिन्हें आप पास करना चाहते हैं।
गारेथ लैटी

59

GUI प्रोग्रामिंग में लैम्ब्डा अत्यंत उपयोगी हैं। उदाहरण के लिए, हम कहते हैं कि आप बटनों का एक समूह बना रहे हैं और आप प्रति बटन एक अद्वितीय कॉलबैक के बजाय एक एकल पैरामैटराइज़्ड कॉलबैक का उपयोग करना चाहते हैं। लैम्ब्डा आपको आसानी से पूरा करने देता है:

for value in ["one","two","three"]:
    b = tk.Button(label=value, command=lambda arg=value: my_callback(arg))
    b.pack()

(नोट: हालाँकि यह प्रश्न विशेष रूप से इसके बारे में पूछ रहा है lambda, आप एक ही प्रकार के परिणाम प्राप्त करने के लिए functionalools.partial का उपयोग कर सकते हैं )

विकल्प प्रत्येक बटन के लिए एक अलग कॉलबैक बनाने के लिए है जो डुप्लिकेट कोड को जन्म दे सकता है।


1
यह ठीक यही है कि मैंने यह देखा कि लैम्ब्डा क्या था, लेकिन यह काम क्यों करता है, मेरे लिए यह ठीक वैसा ही दिखता है जैसे कि फ़ंक्शन को सीधे कॉल करना ( stackoverflow.com/questions/3704568/… )। शायद देर हो गई, यह काम करता है, लेकिन यह काम क्यों करता है?
Rqomey

5
@ रिकी: अंतर यह है कि इस उदाहरण valueमें एक लूप में परिभाषित किया गया है; दूसरे उदाहरण में पैरामीटर का हमेशा केवल एक मूल्य होता है। जब आप कुछ ऐसा जोड़ते हैं arg=value, तो आप कॉलबैक के लिए वर्तमान मूल्य संलग्न कर रहे हैं। इसके बिना, आप कॉलबैक में चर के संदर्भ को बांधते हैं। संदर्भ में हमेशा चर का अंतिम मूल्य होगा, क्योंकि कॉलबैक कुछ समय बाद होता है जब लूप पहले ही समाप्त हो चुका होता है।
ब्रायन ओकले

1
मुझे कल ही यह काम मिल गया था, मैं ईमानदारी से विश्वास नहीं कर सकता कि यह कितना उपयोगी है ... मैं लूप के लिए एक से एक मेनू और कॉन्फ़िगरेशन के लिए एक सीएसवी फ़ाइल बना सकता हूं। वास्तव में उपयोगी सामान।
Rqomey

1
उस अस्तित्व पर ध्यान दें, functools.partial()जो आपको कम क्रॉफ्ट (और बिना lambda) के साथ ऐसा करने की अनुमति देता है ।
गारेथ लैट्टी

2
partial(my_callback, value)बनाम lambda arg=value: my_callback(arg)- लैम्ब्डा में बहुत अधिक क्रुफ्ट (आर्ग और फिर उपयोग करने के लिए असाइनमेंट) है और यह कम स्पष्ट है कि इरादा क्या है (आप लैम्ब्डा में कुछ अलग कर सकते हैं)। आयात वास्तव में एक समस्या नहीं है (आपके पास वैसे भी ढेर है और यह एक बार प्रति फ़ाइल है)। कोड को सबसे अच्छा आंका जाता है कि वह कितना अच्छा पढ़ता है, और partial()लंबोदर की तुलना में पढ़ना बहुत आसान है।
गारेथ लैटी

58

मुझे संदेह है कि लंबोदर चले जाएंगे। आखिरकार गुइडो की पोस्ट देखें कि इसे हटाने की कोशिश की जा रही है। संघर्ष की रूपरेखा भी देखें ।

पायथन की कार्यात्मक विशेषताओं के पीछे के सौदे के बारे में अधिक जानकारी के लिए आप इस पोस्ट को देख सकते हैं: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

उत्सुकता से, नक्शे, फ़िल्टर, और उन कार्यों को कम करते हैं जो मूल रूप से लैम्ब्डा और अन्य कार्यात्मक सुविधाओं की शुरूआत को प्रेरित करते हैं, उन्हें काफी हद तक सूची समझ और जनरेटर अभिव्यक्तियों से अलग किया गया है। वास्तव में, पायथन 3.0 में निर्मित कार्यों की सूची से कम फ़ंक्शन को हटा दिया गया था। (हालांकि, लंबोदा, नक्शे या फिल्टर को हटाने के बारे में शिकायतों में भेजना आवश्यक नहीं है: वे रह रहे हैं। :-)

मेरे अपने दो सेंट: शायद ही लांबा इसके लायक है जहाँ तक स्पष्टता जाती है। आम तौर पर एक अधिक स्पष्ट समाधान होता है जिसमें लैम्बडा शामिल नहीं होता है।


2
ध्यान दें कि पायथन 3.0 में अभी भी आयात कम है। यदि आप वास्तव में यह चाहते हैं, तो आप अभी भी यह कर सकते हैं।
पावेल पोल्विकेज़

मुझे लगता है कि सिंटेक्स के बारे में गुइडो का प्रयास अधिक था। यह व्यक्ति यह भी सोचता है कि: cackhanded.com/blog/post/2008/01/24/…
leewz

38

पायथन में, lambdaइनलाइन फ़ंक्शन को परिभाषित करने का एक तरीका है,

a = lambda x: x + 1
print a(1)

तथा..

def a(x): return x + 1
print a(1)

..are सटीक एक ही।

कुछ भी नहीं है जो आप लैम्ब्डा के साथ कर सकते हैं जो आप एक नियमित फ़ंक्शन के साथ नहीं कर सकते हैं - पायथन कार्यों में कुछ और की तरह एक वस्तु है, और लैम्ब्डा बस एक फ़ंक्शन को परिभाषित करते हैं:

>>> a = lambda x: x + 1
>>> type(a)
<type 'function'>

मुझे ईमानदारी से लगता है कि lambdaपायथन में कीवर्ड बेमानी है- मुझे उन्हें इस्तेमाल करने की कभी आवश्यकता नहीं थी (या किसी को जहां एक नियमित कार्य, एक सूची-समझ या कई अंतर्निहित कार्यों में से एक का उपयोग किया जा सकता था, उनके बजाय इसका बेहतर उपयोग किया जा सकता है)

एक पूरी तरह से यादृच्छिक उदाहरण के लिए, "पायथन का लंबोदा टूट गया है" लेख से ! :

यह देखने के लिए कि लैम्ब्डा कैसे टूटा है, कार्यों की एक सूची बनाने का प्रयास करें fs=[f0,...,f9]जहां fi(n)=i+n। पहला प्रयास:

>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13

मैं तर्क करूंगा, भले ही वह काम किया हो, यह बहुत ही भयानक और "अनहाइथोनिक" है, वही कार्यक्षमता अनगिनत अन्य तरीकों से लिखी जा सकती है, उदाहरण के लिए:

>>> n = 4
>>> [i + n for i in range(10)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

हां, यह समान नहीं है, लेकिन मैंने कभी ऐसा कारण नहीं देखा है जहां एक सूची में लंबो कार्यों के समूह को बनाने की आवश्यकता होती है। यह अन्य भाषाओं में समझ में आ सकता है, लेकिन पायथन हास्केल (या लिस्प, या ...) नहीं है

कृपया ध्यान दें कि हम लैम्ब्डा का उपयोग कर सकते हैं और फिर भी इस तरह से वांछित परिणाम प्राप्त कर सकते हैं:

>>> fs = [(lambda n,i=i: i + n) for i in range(10)]
>>> fs[3](4)
7

संपादित करें:

ऐसे कुछ मामले हैं जहां लैम्ब्डा उपयोगी है, उदाहरण के लिए, यह अक्सर सुविधाजनक होता है जब PyQt अनुप्रयोगों में सिग्नल कनेक्ट करते हैं, जैसे:

w = PyQt4.QtGui.QLineEdit()
w.textChanged.connect(lambda event: dothing())

बस करने से एक अतिरिक्त तर्क के साथ विधि w.textChanged.connect(dothing)को कॉल किया जाएगा और एक त्रुटि का कारण होगा। लंबो का उपयोग करने का मतलब है कि हम रैपिंग फ़ंक्शन को परिभाषित किए बिना तर्क को ख़ुशी से छोड़ सकते हैं।dothingevent


2
आपके "लंबोदा टूटा हुआ है" तर्क टूट गया है, क्योंकि अजगर चर स्कूपिंग नियम उस तरह से काम करते हैं, अवधि। यदि आपने लूप के अंदर एक क्लोजर बनाया है तो आपको उसी तरह काट दिया जाएगा।
अंती हापाला

1
लैम्ब्डा केवल "गुमनाम" फ़ंक्शन के साथ उपयोगकर्ता को प्रदान करने के लिए अजगर का तरीका है, जैसे कई अन्य भाषाओं में है (जैसे, जावास्क्रिप्ट)।
स्टीफन ग्रुएनवाल्ड

1
लैंबडा और फ़ंक्शन aजिसे आपने परिभाषित किया है, वास्तव में समान नहीं हैं । :) वे __name__कम से कम क्षेत्र से भिन्न होते हैं ...
nperson325681

1
यह सिर्फ एक इनलाइन फ़ंक्शन से अधिक काम करता है।
काटा

"किसी अन्य भाषा में समझदारी" के बारे में आपका तर्क अजीब है। या तो लैम्ब्डा के आंतरिक गुण हैं, या वे नहीं हैं।
टिटौ

31

मुझे उन कार्यों की सूची के लिए लैंबडा उपयोगी लगता है जो समान हैं, लेकिन विभिन्न परिस्थितियों के लिए।

जैसा मोज़िला बहुवचन नियम :

plural_rules = [
    lambda n: 'all',
    lambda n: 'singular' if n == 1 else 'plural',
    lambda n: 'singular' if 0 <= n <= 1 else 'plural',
    ...
]
# Call plural rule #1 with argument 4 to find out which sentence form to use.
plural_rule[1](4) # returns 'plural'

यदि आपको उन सभी के लिए एक फ़ंक्शन को परिभाषित करना है जो आप इसके अंत तक पागल हो जाएंगे।
इसके अलावा, यह फ़ंक्शन नाम जैसे plural_rule_1, plural_rule_2आदि के साथ अच्छा नहीं होगा और आपको इसकी आवश्यकता तब होगी eval()जब आप एक चर फ़ंक्शन आईडी पर निर्भर होंगे।


1
यह उन संक्षिप्त मुठभेड़ों के समान है जो मैंने पैटर्न मिलान और विकल्पों के साथ एफ # में अब तक किए हैं। क्या आपके पास इस सिंटैक्स का उपयोग करने के बारे में अधिक जानकारी है?
केन

26

बहुत कुछ भी आप अपने साथ lambdaकर सकते हैं या तो नामित कार्यों या सूची और जनरेटर के भावों के साथ बेहतर कर सकते हैं।

नतीजतन, अधिकांश भाग के लिए आपको मूल रूप से किसी भी स्थिति (इंटरएक्टिव इंटरप्रेटर में लिखे गए स्क्रैच कोड को छोड़कर) में से एक होना चाहिए।


3
"अधिकांश भाग के लिए आपको मूल रूप से किसी भी स्थिति में उनमें से सिर्फ एक होना चाहिए" अवधि। इंटरप्रेटर में लैम्ब्डा टाइप करना भी उतना मददगार नहीं है।
एस.लॉट

11
@ जेवियर मैं आपसे सहमत हूँ अगर आप "लंबोदर" अवधारणा के बारे में बात कर रहे हैं; हालाँकि, अगर हम "लैम्ब्डा" के बारे में बात कर रहे हैं तो python कीवर्ड: 1) नाम वाले फ़ंक्शंस तेज़ हैं और अधिक (कथन + अभिव्यक्तियाँ) कर सकते हैं लगभग कहीं भी आप लैम्ब्डा (मैप + फ़िल्टर) का उपयोग करेंगे आप केवल जनरेटर के भाव या सूची संकलन कर सकते हैं जो अधिक प्रदर्शन और संक्षिप्त हैं। मैं यह नहीं कह रहा हूं कि प्रथम श्रेणी के कार्य शांत नहीं हैं, बस इतना है कि अजगर में "लैम्ब्डा" कीवर्ड केवल एक नामित फ़ंक्शन का उपयोग करने के रूप में अच्छा नहीं है, बस।
आरोन मेंपा

3
लैम्ब्डा मेरे लिए उन कार्यों के साथ उपयोग करने के लिए अपरिहार्य है, जो कॉलबैक तर्क जैसे कि = = सॉर्ट () और सॉर्ट करने के लिए तर्क लेते हैं ()
रिक कोपलैंड

19
@ मुझे संदेह नहीं है, लेकिन वास्तविकता यह है कि जब आप "लैम्ब्डा" देखते हैं और आपको लगता है कि "ज़ोहिमगॉड लैम्ब्डा" और पायथन में स्कीम कोड लिखना शुरू कर दें, तो आप पाइथन के लैम्ब्डा अभिव्यक्ति की सीमाओं से निराश होंगे। दूसरी ओर, यदि आप अपने आप से सोचना शुरू करते हैं "क्या एक सूची समझने का काम करेगा? नहीं, नामांकित फ़ंक्शन होने से मुझे क्या आवश्यकता होगी? नंबर ठीक है: सॉर्ट किया गया (xs, कुंजी = lambda x: x.name, x.height) ", आप संभवतया लंबोदा का सही समय पर उपयोग कर लेंगे।
आरोन मेंपा

4
+1: मैं इस बात पर जोर नहीं दे सकता कि जब कोई लैम्बडा का उपयोग करता है तो कोई एक अनाम फ़ंक्शन का उपयोग करता है । और नामों में एक बहुमूल्य बौद्धिक जोड़ा मूल्य है।
स्टीफन रोलैंड

19

मैं कुछ वर्षों से पायथन का उपयोग कर रहा हूं और मैं उस मामले में कभी नहीं चला हूं जहां मुझे लैम्ब्डा की आवश्यकता है । वास्तव में, जैसा कि ट्यूटोरियल बताता है, यह सिंटैक्टिक शुगर के लिए है।


8
अजगर का उपयोग करके जीयूआई विकसित करते समय वे बहुत उपयोगी होते हैं । अक्सर, विगेट्स को फ़ंक्शन के संदर्भ की आवश्यकता होती है। यदि आपको किसी फ़ंक्शन को कॉल करने और तर्कों को पास करने के लिए विजेट की आवश्यकता है, तो लैम्बडा ऐसा करने का एक बहुत ही सुविधाजनक तरीका है।
ब्रायन ओकली

1
फ़ंक्शन में कई तर्क पास करने से क्या फायदा है? func_name (a, b): lambda
dter

2
इसकी आवश्यकता नहीं है, लेकिन यह छोटे कोड और कई मामलों में पठनीय लिखने में मदद करता है, esp। जावा या C ++ जैसी
क्रियात्मक

17

मैं अजगर के मेमने के विशेष कार्यान्वयन के लिए बात नहीं कर सकता, लेकिन सामान्य रूप से मेमने के कार्य वास्तव में आसान हैं। वे कार्यात्मक प्रोग्रामिंग की एक मुख्य तकनीक (शायद तकनीक भी हैं), और वे वस्तु-उन्मुख कार्यक्रमों में भी बहुत उपयोगी हैं। कुछ प्रकार की समस्याओं के लिए, वे सबसे अच्छा समाधान हैं, इसलिए निश्चित रूप से नहीं भूलना चाहिए!

मेरा सुझाव है कि आप क्लोजर और मैप फ़ंक्शन पर पढ़ते हैं (जो कि अजगर डॉक्स से लिंक करता है, लेकिन यह लगभग हर भाषा में मौजूद है जो कार्यात्मक निर्माण का समर्थन करता है) यह देखने के लिए कि यह क्यों उपयोगी है।


3
वह सामान बिना लंबोदर के किया जा सकता है। यह सिर्फ एक बड़ी परेशानी है।
ब्रायन

17

एक समारोह बनाने के लिए यह एक गैर-नौकरशाही तरीका है।

बस। उदाहरण के लिए, मान लें कि आपके पास अपना मुख्य कार्य है और वर्ग मानों की आवश्यकता है। आइए देखें पारंपरिक तरीका और ऐसा करने का लंबोदर तरीका:

पारंपरिक तरीका:

def main():
...
...
y = square(some_number)
...
return something

def square(x):
    return x**2

मेमने का तरीका:

def main():
...
square = lambda x: x**2
y = square(some_number)
return something

फर्क देखें?

लैंबडा फ़ंक्शंस सूचियों के साथ बहुत अच्छी तरह से चलते हैं, जैसे सूचियां समझ या नक्शा। वास्तव में, सूची की समझ यह "पाइथोनिक" तरीका है जो स्वयं को लैम्ब्डा का उपयोग करने के लिए व्यक्त करता है। उदाहरण के लिए:

>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]

आइए देखें कि वाक्य रचना के प्रत्येक तत्व का क्या अर्थ है:

[]: "मुझे एक सूची दें"

x ** 2: "इस नए जन्मे समारोह का उपयोग"

एक्स फॉर ए: "प्रत्येक तत्व में"

यह सुविधाजनक उह है? इस तरह के कार्य बनाना। लेम्बडा का उपयोग करके इसे फिर से लिखें:

>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]

अब हम मानचित्र का उपयोग करते हैं, जो समान है, लेकिन अधिक भाषा-तटस्थ है। मानचित्र में 2 तर्क दिए गए हैं:

(i) एक कार्य

(ii) एक चलने योग्य

और आपको एक सूची प्रदान करता है जहां प्रत्येक तत्व यह फ़ंक्शन है जो चलने वाले के प्रत्येक तत्व पर लागू होता है।

इसलिए, हमारे पास मानचित्र का उपयोग करना होगा:

>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)

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


13

lambdaमेरी राय में इसके बारे में एक अच्छी बात यह है कि मूल्य की आवश्यकता होने तक सरल रूपों के लिए मूल्यांकन को स्थगित करना इसका तरीका है। मुझे समझाने दो।

कई पुस्तकालय दिनचर्या को लागू किया जाता है ताकि वे कुछ मापदंडों को कॉलबेल होने दें (जिनमें से लैम्ब्डा एक है)। विचार यह है कि वास्तविक मूल्य की गणना केवल उस समय की जाएगी जब इसका उपयोग होने वाला हो (बल्कि यह कि जब इसे बुलाया जाए)। बिंदु को चित्रित करने में एक (आकस्मिक) उदाहरण मदद कर सकता है। मान लीजिये आपकी कोई दिनचर्या है जो किसी दिए गए टाइमस्टैम्प को लॉग इन करने जा रही है। आप चाहते हैं कि रूटीन वर्तमान समय माइनस 30 मिनट का उपयोग करें। आप इसे ऐसा कहते हैं

log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30))

अब मान लें कि वास्तविक कार्य तभी कहा जाएगा जब कोई निश्चित घटना घटती है और आप चाहते हैं कि टाइमस्टैम्प की गणना केवल उस समय की जाए। आप ऐसा कर सकते हैं

log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30))

मान log_timestampसकते हैं कि इस तरह से कॉलबल्स को संभाल सकते हैं, यह इसका मूल्यांकन करेगा जब इसे इसकी आवश्यकता होगी और आप उस समय टाइमस्टैम्प प्राप्त करेंगे।

ऐसा करने के लिए निश्चित रूप से वैकल्पिक तरीके हैं ( operatorउदाहरण के लिए मॉड्यूल का उपयोग करके ) लेकिन मुझे आशा है कि मैंने बिंदु को बता दिया है।

अद्यतन : यहाँ एक और अधिक ठोस वास्तविक दुनिया उदाहरण है।

अपडेट 2 : मुझे लगता है कि यह एक उदाहरण है जिसे थंक कहा जाता है ।


11

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

जब मैंने कुछ साल पहले पायथन में शुरुआत की थी, तो मैंने लिम्बडास का उपयोग किया, यह सोचकर कि वे शांत थे, साथ ही सूची समझ भी थी। हालाँकि, मैंने पायथन में लिखी गई एक बड़ी वेबसाइट को बनाए रखा और कई हज़ार फंक्शन पॉइंट्स के ऑर्डर के साथ लिखा। मैंने अनुभव से सीखा है कि लैम्ब्डा के साथ प्रोटोटाइप चीजों के लिए ठीक हो सकता है, लेकिन इनलाइन फ़ंक्शंस (बंद किए गए नाम) पर कुछ की-स्टोक्स को बचाने के अलावा, या कभी-कभी कुछ भी नहीं की पेशकश करें।

मूल रूप से यह कई बिंदुओं को उबालता है:

  • सॉफ्टवेयर को पढ़ना आसान है जो स्पष्ट रूप से सार्थक नामों का उपयोग करके लिखा गया है। परिभाषा के अनुसार अनाम बंद होने का कोई सार्थक नाम नहीं हो सकता है, क्योंकि उनका कोई नाम नहीं है। यह संक्षिप्तता किसी कारण से, लैम्ब्डा मापदंडों को भी संक्रमित करती है, इसलिए हम अक्सर लैम्ब्डा x: x + 1 जैसे उदाहरण देखते हैं।
  • नाम बंद होने का पुन: उपयोग करना आसान है, क्योंकि उन्हें एक से अधिक बार नाम से संदर्भित किया जा सकता है, जब उनके द्वारा संदर्भित करने के लिए एक नाम होता है।
  • यह कोड डीबग करना अधिक आसान है जो लंबोदर के बजाय नामित क्लोजर का उपयोग कर रहा है, क्योंकि नाम ट्रेसबैक में और त्रुटि के आसपास दिखाई देगा।

यही कारण है कि उन्हें गोल करने और नामित क्लोजर में बदलने के लिए पर्याप्त कारण है। हालांकि, मैं अनाम बंद होने के खिलाफ दो अन्य grudges पकड़।

पहली शिकायत केवल यह है कि वे भाषा को अव्यवस्थित करने वाले एक और अनावश्यक कीवर्ड हैं।

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

  • एक निहित रिटर्न है, यानी वे ऐसा लगता है जैसे वे 'कार्य' होना चाहिए।

  • वे दूसरे के लिए एक वैकल्पिक राज्य-छिपाई तंत्र हैं, अधिक स्पष्ट, अधिक पठनीय, अधिक पुन: प्रयोज्य और अधिक सामान्य तंत्र: विधियाँ।

मैं लैम्बडा-मुक्त पायथन लिखने की कोशिश करता हूं, और दृष्टि पर लंबोदर को हटाता हूं। मुझे लगता है कि पैंथन लैम्ब्डा के बिना थोड़ी बेहतर भाषा होगी, लेकिन यह सिर्फ मेरी राय है।


1
"... पायथन कार्यों में बंद हैं"। यह बिल्कुल सही नहीं है, जैसा कि मैं इसे समझता हूं। क्लोजर फ़ंक्शंस हैं, लेकिन फ़ंक्शंस हमेशा बंद नहीं होते हैं। फंक्शन-> लैम्ब्डा एक्स, वाई: एक्स + वाई। समापन-> लैम्ब्डा x: लैम्ब्डा y: x + y
0atman

6
"क्योंकि लैम्ब्डा कैलकुलस ट्यूरिंग-कम्प्लीट नहीं है" सादा गलत है, अनपेड लैम्ब्डा कैलकुलस IS ट्यूरिंग कम्प्लीट है, यही कारण है कि यह इतना महत्वपूर्ण है। आप वाई-कॉम्बिनेटर का उपयोग करके पुनरावृत्ति प्राप्त कर सकते हैं,Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
एंटी हापाला

इसके अलावा, अगर कोई ट्यूरिंग पूर्णता पर पढ़ने के लिए विकिपीडिया पर जाता है, तो यह कहता है कि "एक क्लासिक उदाहरण लंबोदर कलन है।"
एंटटी हापाला

गंभीरता से - ट्यूरिंग पूरा नहीं - इस उत्तर को एक गंभीर संपादन या वापसी की आवश्यकता है।
टोनी सफ़ोकल 66

@ MarcinŁoś ऊपर मतदान क्योंकि यह KISS का पालन करता है। तुलना के रूप में, K & R पुस्तक का उल्लेख है कि भाग के रूप में असाइनमेंट का उपयोग करते समय या एक बड़ी अभिव्यक्ति अधिक कॉम्पैक्ट है, यह अक्सर कम पठनीय होता है। कार्यात्मक प्रोग्रामिंग पैटर्न का उपयोग करने की प्रवृत्ति-वैगन ट्राइट और क्लिच है। यह बताने के लिए पर्याप्त है कि उनका उपयोग कैसे किया जा सकता है, लेकिन यह बताने के लिए अति उत्साही है कि वे एक सक्षम डेवलपर बनने के लिए सर्वोपरि हैं; पूरी तरह से व्यक्तिपरक। यह तर्क C ++ डेवलपर्स के अनुरूप है जो तर्क देते हैं कि भाषा w / o वर्ग आदिम, हीन और अपर्याप्त हैं। "ट्यूरिंग-पूर्णता", तर्क पांडित्यपूर्ण हैं।
टाइपराइफ

11

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

लैंबडस भ्रमित होने की प्रवृत्ति रखते हैं, लेकिन एक बार एक ठोस समझ प्राप्त करने के बाद, आप इस तरह से स्वच्छ सुरुचिपूर्ण कोड लिख सकते हैं:

squared = map(lambda x: x*x, [1, 2, 3, 4, 5])

कोड की उपरोक्त पंक्ति सूची में संख्याओं के वर्गों की एक सूची लौटाती है। बेशक, आप भी इसे कर सकते हैं जैसे:

def square(x):
    return x*x

squared = map(square, [1, 2, 3, 4, 5])

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

इसके अलावा, जैसा कि @David Zaslavsky ने अपने उत्तर में उल्लेख किया है, सूची की समझ हमेशा विशेष रूप से जाने का तरीका नहीं है यदि आपकी सूची में कुछ अस्पष्ट गणितीय तरीके से मूल्यों को प्राप्त करना है।

अधिक व्यावहारिक दृष्टिकोण से, मेरे लिए लैम्बदास का सबसे बड़ा लाभ हाल ही में जीयूआई और इवेंट-संचालित प्रोग्रामिंग में हुआ है। यदि आप टिंकर में कॉलबैक पर एक नज़र डालते हैं, तो वे सभी तर्क के रूप में लेते हैं, यह घटना है जिसने उन्हें ट्रिगर किया। उदाहरण के लिए

def define_bindings(widget):
    widget.bind("<Button-1>", do-something-cool)

def do-something-cool(event):
    #Your code to execute on the event trigger

अब अगर आपके पास पास करने के लिए कुछ तर्क हैं तो क्या होगा? माउस-क्लिक के निर्देशांक को संग्रहीत करने के लिए 2 तर्क पारित करने के रूप में सरल कुछ। आप इसे आसानी से इस तरह से कर सकते हैं:

def main():
    # define widgets and other imp stuff
    x, y = None, None
    widget.bind("<Button-1>", lambda event: do-something-cool(x, y))

def do-something-cool(event, x, y):
    x = event.x
    y = event.y
    #Do other cool stuff

अब आप तर्क दे सकते हैं कि यह वैश्विक चर का उपयोग करके किया जा सकता है, लेकिन क्या आप वास्तव में स्मृति प्रबंधन और रिसाव के बारे में चिंता करने के लिए अपने सिर को पीटना चाहते हैं, खासकर यदि वैश्विक चर का उपयोग केवल एक विशेष स्थान पर किया जाएगा? यह सिर्फ घटिया प्रोग्रामिंग शैली होगी।

संक्षेप में, लंबोदर कमाल के हैं और उन्हें कभी कम नहीं आंका जाना चाहिए। पाइथन लैम्ब्डा हालांकि LISP लैम्ब्डा के समान नहीं हैं (जो अधिक शक्तिशाली हैं), लेकिन आप वास्तव में उनके साथ बहुत सारे जादुई सामान कर सकते हैं।


धन्यवाद। मैं आपके अंतिम उदाहरण को पूरी तरह से समझ नहीं पाया। कैसे आओ x और y दोनों में परिभाषित किया गया है mainऔर do_something_cool? क्या होता है xऔर yफंक्शन में? पारित मान तुरंत अधिलेखित होने लगते हैं? फ़ंक्शन के बारे में कैसे पता चलता है event? क्या आप कुछ टिप्पणी / स्पष्टीकरण जोड़ सकते हैं? साभार
संजय मनोहर

@SanjayManohar मैं गुजर रहा xहै और yकरने के लिए तर्क के रूप में do-something-coolऔर उनके मान वर्णन करने के लिए कैसे आप तर्क जहां कोई भी उम्मीद कर रहे हैं पारित करने के लिए उपयोग कर सकते हैं lambdas समारोह में सेट किया जा रहा है। widget.bindसमारोह एक उम्मीद eventपैरामीटर जो कि विशेष रूप से विजेट पर जीयूआई घटना को पहचानती है। मैं अधिक स्पष्टता के लिए टिंकर के प्रोग्रामिंग मॉडल पर पढ़ने की सलाह देता हूं।
5

हम्म मुझे लगता है कि मैं टिंकर मॉडल को समझता हूं। लेकिन अभी भी काफी समझ में नहीं आता है - आप x,yतब करते हैं x=event.x। क्या आपके द्वारा पास किए गए मान को अधिलेखित नहीं किया गया है? और फ़ंक्शन कैसे जानता है कि क्या eventहै? मैं यह नहीं देखता कि आप इस समारोह में कहां से गुजरते हैं। या यह एक विधि है? क्या आपको फ़ंक्शन नाम में माइनस साइन की अनुमति है?
संजय मनोहर

@SanjayManohar दोस्त आपको टिंकर और पायथन पर पढ़ना होगा। Tkinter फ़ंक्शन को डिफ़ॉल्ट क्रिया के रूप में फ़ंक्शन ऑब्जेक्ट पास करता है। के रूप में x, y, कि उदाहरण के प्रयोजनों के लिए सिर्फ एक उदाहरण है। मैं लैम्ब्डा की शक्ति दिखाने की कोशिश कर रहा हूं, न कि टिंकर। :)
varagrawal

1
ठीक है अब मैं देख रहा हूँ कि आपका क्या इरादा है - आप चाहते हैं कि समारोह प्राप्त हो event? उस स्थिति में, क्या आपका मेमना नहीं पढ़ना चाहिए lambda event: do_something_cool(event,x,y)?
संजय मनोहर

8

लैम्ब्डा सामान्य रूप से कार्यात्मक प्रोग्रामिंग शैली से गहराई से जुड़ा हुआ है। यह विचार कि आप कुछ डेटा के लिए एक फ़ंक्शन लागू करके और परिणामों को मर्ज करके समस्याओं को हल कर सकते हैं, वह है जो Google अपने अधिकांश एल्गोरिदम को लागू करने के लिए उपयोग करता है।

कार्यात्मक प्रोग्रामिंग शैली में लिखे गए कार्यक्रम आसानी से समानांतर हो जाते हैं और इसलिए आधुनिक मल्टी-कोर मशीनों के साथ अधिक से अधिक महत्वपूर्ण होते जा रहे हैं। तो संक्षेप में, नहीं, आपको उन्हें नहीं भूलना चाहिए।


7

पहले बधाई जो लंबोदर का पता लगाने में कामयाब रही। मेरी राय में यह वास्तव में शक्तिशाली कार्य है। कार्यात्मक प्रोग्रामिंग भाषाओं की ओर इन दिनों रुझान निश्चित रूप से एक संकेतक है कि इसे न तो टाला जाना चाहिए और न ही निकट भविष्य में इसे फिर से परिभाषित किया जाएगा।

आपको बस थोड़ा अलग सोचना होगा। मुझे यकीन है कि जल्द ही आप इसे पसंद करेंगे। लेकिन सावधान रहें यदि आप केवल अजगर से निपटते हैं। क्योंकि लैम्ब्डा असली बंद नहीं है, यह किसी भी तरह "टूटा हुआ" है: अजगर लैम्ब्डा टूट गया है


अजगर का मेमना नहीं टूटा है। लैम्ब्डा में स्थानीय लोगों को संभालने के दो तरीके हैं। दोनों के फायदे और नुकसान हैं। मुझे लगता है कि पाइथन (और C #) का दृष्टिकोण संभवतः उन लोगों के लिए प्रतिवादपूर्ण है जो विशुद्ध रूप से कार्यात्मक भाषाओं के आदी हैं, क्योंकि विशुद्ध रूप से कार्यात्मक भाषा के साथ मुझे नहीं लगता कि दृष्टिकोण भी समझ में आता है।
ब्रायन

यह वास्तव में counterintuitive है। मैं एक अजगर प्रोग्रामर नहीं हूँ, लेकिन चीख़ के छोटे से छोटे हिस्से में भी ऐसा ही है और मैं नियमित रूप से इस पर डगमगाता हूँ। तो यहां तक ​​कि मैं इसे "टूटा हुआ"
मानूंगा

नहीं, इसका प्रतिवाद से कोई लेना-देना नहीं है। यह सिर्फ इतना है कि चर नामों का शाब्दिक दायरा एक फ़ंक्शन है; एक लूप एक शाब्दिक गुंजाइश का परिचय नहीं देता है। जावास्क्रिप्ट में भी फ़ंक्शंस उसी तरह काम करते हैं। यदि आपको var के लिए स्कोप की आवश्यकता है, तो आप हमेशा कर सकते हैं (lambda scopedvar: lambda x: scopedvar + x) ()
एंटी हापाला

6

मैं अभी पाइथन की शुरुआत कर रहा हूं और सबसे पहले लैम्बडा में गया, जो मुझे पता लगाने में थोड़ी देर लगी।

ध्यान दें कि यह किसी भी चीज़ की निंदा नहीं है। हर किसी के पास चीजों का एक अलग सेट है जो आसानी से नहीं आता है।

क्या लैम्ब्डा उन 'दिलचस्प' भाषा वस्तुओं में से एक है जिन्हें वास्तविक जीवन में भुला दिया जाना चाहिए?

नहीं।

मुझे यकीन है कि कुछ किनारे मामले हैं जहां इसकी आवश्यकता हो सकती है, लेकिन इसकी अस्पष्टता को देखते हुए,

यह अस्पष्ट नहीं है। मैंने जिन 2 टीमों पर काम किया है, हर कोई हर समय इस सुविधा का उपयोग करता है।

भविष्य के विमोचन में इसकी क्षमता को फिर से परिभाषित किया जा रहा है (इसकी विभिन्न परिभाषाओं के आधार पर मेरी धारणा)

मैंने कुछ साल पहले बंद किए गए शब्दार्थ को ठीक करने से परे, पायथन में इसे फिर से परिभाषित करने के लिए कोई गंभीर प्रस्ताव नहीं देखा है।

और कम कोडिंग स्पष्टता - क्या इसे टाला जाना चाहिए?

यह कम स्पष्ट नहीं है, यदि आप इसे सही उपयोग कर रहे हैं। इसके विपरीत, अधिक भाषा निर्माण उपलब्ध होने से स्पष्टता बढ़ती है

यह मुझे C प्रकार के ओवरफ्लो (बफर ओवरफ्लो) की याद दिलाता है - शीर्ष चर की ओर इशारा करते हुए और अन्य क्षेत्र मूल्यों को सेट करने के लिए ओवरलोडिंग ... एक तकनीकी शो के प्रकार लेकिन रखरखाव कोडर दुःस्वप्न ।।

लैम्ब्डा बफर ओवरफ्लो की तरह है? वाह। मैं कल्पना नहीं कर सकता कि आप लैम्बडा का उपयोग कैसे कर रहे हैं यदि आपको लगता है कि यह "रखरखाव बुरा सपना" है।


5
-1 (मुझे और अन्य) बनाने के लिए पूरे प्रश्न को फिर से पढ़ें। ध्यान दें कि अन्य ऐसा करने के बिना जवाब देने में कामयाब रहे।
पावेल पोल्विकेज़

6

कोड डुप्लीकेशन से बचने के लिए मैं लैम्ब्डा का उपयोग करता हूं। यह समारोह को आसानी से समझ में आता है जैसे:

def a_func()
  ...
  if some_conditon:
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)
  else
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)

मैं एक टेम्पर्ड लैम्ब्डा के साथ इसे प्रतिस्थापित करता हूं

def a_func()
  ...
  call_big_f = lambda args_that_change: call_some_big_func(arg1, arg2, arg3, args_that_change)
  if some_conditon:
     ...
     call_big_f(argX)
  else
     ...
     call_big_f(argY)

5

मैंने आज डेविड मेर्टज़ की किताब 'पायथन में टेक्स्ट प्रोसेसिंग' को पढ़ना शुरू किया। जबकि उनके पास लैम्बडा के उदाहरणों का एक बहुत ही संक्षिप्त विवरण है, जो पहले अध्याय में दिए गए उदाहरणों के परिशिष्ट A में दिए गए स्पष्टीकरण के साथ मिलकर उन्हें मेरे (आखिरकार) पृष्ठ के लिए कूद गया और अचानक मुझे उनका मूल्य समझ में आया। यह कहना नहीं है कि उनकी व्याख्या आपके लिए काम करेगी और मैं अभी भी खोज के चरण में हूं इसलिए मैं निम्नलिखित के अलावा इन प्रतिक्रियाओं को जोड़ने का प्रयास नहीं करूंगा: मैं पायथन के लिए नया हूं मैं ओओपी के लिए नया हूं लैंबडास मेरे लिए एक संघर्ष था अब जब मैं मर्ट्ज़ पढ़ता हूं, मुझे लगता है कि मैं उन्हें प्राप्त करता हूं और मैं उन्हें बहुत उपयोगी देखता हूं क्योंकि मुझे लगता है कि वे प्रोग्रामिंग के लिए एक क्लीनर दृष्टिकोण की अनुमति देते हैं।

वह पायथन के ज़ेन को पुन: पेश करता है, जिसमें से एक पंक्ति सरल है जो जटिल से बेहतर है। एक गैर-ओओपी प्रोग्रामर के रूप में लैम्बदास के साथ (और पिछले सप्ताह की सूची समझ तक) रीडिंग कोड मैंने सोचा है- यह सरल है? । मुझे आखिरकार आज एहसास हुआ कि वास्तव में ये विशेषताएं कोड को अधिक पठनीय बनाती हैं, और वैकल्पिक की तुलना में समझ में आता है-जो कि वास्तव में किसी प्रकार का एक लूप है। मुझे यह भी एहसास हुआ कि वित्तीय वक्तव्यों की तरह-पायथन नौसिखिए उपयोगकर्ता के लिए डिज़ाइन नहीं किया गया था, बल्कि इसे उस उपयोगकर्ता के लिए डिज़ाइन किया गया है जो शिक्षित होना चाहता है। मैं विश्वास नहीं कर सकता कि यह भाषा कितनी शक्तिशाली है। जब इसने मुझ पर (आखिरकार) मेमने का उद्देश्य और मूल्य तय किया, तो मैं लगभग 30 कार्यक्रमों में भाग लेना चाहता था और जहां उपयुक्त था, लंबोदर में डालना शुरू कर दिया।


5

लम्बदा का उपयोग करने के लिए एक उपयोगी मामला लंबी सूची की समझ की पठनीयता में सुधार करना है । इस उदाहरण loop_dicमें स्पष्टता कम है लेकिन कल्पना loop_dicबहुत लंबी है। यदि आप सिर्फ एक सादे मूल्य का उपयोग करेंगे जिसमें iउस मूल्य के लंबोदर संस्करण के बजाय शामिल है जो आपको मिलेगा NameError

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

के बजाय

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

5

मैं आपको एक उदाहरण दे सकता हूं जहां मुझे वास्तव में गंभीर गंभीर की जरूरत थी। मैं एक ग्राफ़िकल प्रोग्राम बना रहा हूँ, जहाँ उपयोग एक फाइल पर राइट क्लिक करता है और तीन विकल्पों में से एक को असाइन करता है। यह पता चला है कि टिंकर में (GUI इंटरफेसिंग प्रोग्राम जो मैं यह लिख रहा हूं), जब कोई व्यक्ति एक बटन दबाता है, तो इसे एक कमांड को नहीं सौंपा जा सकता जो तर्क में लेता है। इसलिए अगर मैंने विकल्पों में से एक को चुना और मेरी पसंद का परिणाम चाहिए:

print 'hi there'

फिर कोई बड़ी बात नहीं। लेकिन क्या होगा अगर मुझे एक विशेष विवरण के लिए मेरी पसंद की आवश्यकता है। उदाहरण के लिए, यदि मैं विकल्प A को चुनता हूं, तो यह एक फ़ंक्शन को कॉल करता है जो कुछ तर्क में लेता है जो विकल्प A, B या C पर निर्भर है, TKinter इस का समर्थन नहीं कर सकता है। लैमडा वास्तव में इसके आसपास का एकमात्र विकल्प था ...


2
ठीक है, संभवतः आप कर सकते थे def foo...और फिर के fooबजाय में पारित कर दिया lambda। यह सिर्फ अधिक कोड है और आपको एक नाम के साथ आना होगा।
जॉन कूम्ब्स

4

मैं इसे अक्सर उपयोग करता हूं, मुख्य रूप से एक अशक्त वस्तु के रूप में या किसी फ़ंक्शन को आंशिक रूप से बाँधने के लिए।

यहाँ उदाहरण हैं:

अशक्त वस्तु पैटर्न को लागू करने के लिए:

{
    DATA_PACKET: self.handle_data_packets
    NET_PACKET: self.handle_hardware_packets
}.get(packet_type, lambda x : None)(payload)

पैरामीटर बाइंडिंग के लिए:

मान लीजिए कि मेरे पास निम्नलिखित एपीआई है

def dump_hex(file, var)
    # some code
    pass

class X(object):
    #...
    def packet_received(data):
        # some kind of preprocessing
        self.callback(data)
    #...

तब, जब मैं पुन: प्राप्त डेटा को जल्दी से एक फ़ाइल में डंप नहीं करता, जो मैं करता हूं:

dump_file = file('hex_dump.txt','w')
X.callback = lambda (x): dump_hex(dump_file, x)
...
dump_file.close()

4

मैं उपयोग करता हूं lambda कॉलबैक बनाने के लिए करता जिसमें पैरामीटर शामिल हैं। यह एक कार्यक्षमता को लिखने के लिए एक विधि लिखने की तुलना में एक लाइन में लंबोदर लिखने वाला क्लीनर है।

उदाहरण के लिए:

import imported.module

def func():
    return lambda: imported.module.method("foo", "bar")

विरोध के रूप में:

import imported.module

def func():
    def cb():
        return imported.module.method("foo", "bar")
    return cb

4

मैं एक अजगर शुरुआत कर रहा हूं, इसलिए लंबोदर का स्पष्ट विचार पाने के लिए मैंने इसकी तुलना 'लूप' के साथ की; दक्षता के मामले में। यहाँ कोड है (अजगर 2.7) -

import time
start = time.time() # Measure the time taken for execution

def first():
    squares = map(lambda x: x**2, range(10))
    # ^ Lambda
    end = time.time()
    elapsed = end - start
    print elapsed + ' seconds'
    return elapsed # gives 0.0 seconds

def second():
    lst = []
    for i in range(10):
        lst.append(i**2)
    # ^ a 'for' loop
    end = time.time()
    elapsed = end - start
    print elapsed + ' seconds'
    return elapsed # gives 0.0019998550415 seconds.

print abs(second() - first()) # Gives 0.0019998550415 seconds!(duh)

6
आप timeitमॉड्यूल में दिलचस्पी ले सकते हैं , जो आम तौर पर time.time()मूल्यों को घटाने की तुलना में अधिक सटीक परिणाम देता है ।
केविन

2
हम्म, आपको पहले () और दूसरे () की शुरुआत में अपने टाइमर को पुनरारंभ करने की आवश्यकता नहीं है?
क्नील

2

लैंबडा एक प्रक्रिया निर्माता है। आप रन-टाइम पर कार्यक्रमों को संश्लेषित कर सकते हैं, हालांकि पायथन का लैम्ब्डा बहुत शक्तिशाली नहीं है। ध्यान दें कि बहुत कम लोग उस तरह की प्रोग्रामिंग को समझते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.