আরও বেশি পছন্দনীয়: ল্যাম্বদা ফাংশন বা নেস্টেড ফাংশনগুলি ( def
)?
নিয়মিত ফাংশন ব্যবহার করে ল্যাম্বডা ব্যবহার করার একটি সুবিধা রয়েছে: এগুলি একটি এক্সপ্রেশনে তৈরি করা হয়।
বেশ কয়েকটি ত্রুটি রয়েছে:
- নাম নেই (শুধু
'<lambda>'
)
- কোনও ডকাস্ট্রিং নেই
- কোনও টিকা নেই
- কোন জটিল বিবৃতি
তারা উভয় একই ধরণের বস্তু। এই কারণে, আমি সাধারণত def
ল্যাম্বডাসের পরিবর্তে কীওয়ার্ড দিয়ে ফাংশন তৈরি করতে পছন্দ করি ।
প্রথম পয়েন্ট - তারা একই ধরণের অবজেক্ট
একটি ল্যাম্বডা নিয়মিত ফাংশন হিসাবে একই ধরণের অবজেক্টের ফলস্বরূপ
>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
...
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True
যেহেতু ল্যাম্বডাস ফাংশন, তারা প্রথম শ্রেণীর বস্তু।
উভয় ল্যাম্বডাস এবং ফাংশন:
- আর্গুমেন্ট হিসাবে হিসাবে পাস করা যেতে পারে (নিয়মিত ফাংশন হিসাবে একই)
- যখন বাইরের ফাংশনের মধ্যে তৈরি হয় তখন বাহ্যিক ফাংশনগুলির স্থানীয়দের উপর এটি বন্ধ হয়ে যায়
কিন্তু ল্যাম্বডাস হ'ল ডিফল্টরূপে, এমন কিছু জিনিস হারিয়েছে যা ফাংশনগুলি সম্পূর্ণ ফাংশন সংজ্ঞা সিনট্যাক্সের মাধ্যমে পায়।
একটি লাম্বা __name__
হয়'<lambda>'
লাম্বদাস অজানা ফাংশন, সর্বোপরি, তাই তারা নিজের নাম জানেন না।
>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'
সুতরাং ল্যাম্বডা তাদের নামস্থানে প্রোগ্রামগতভাবে দেখা যাবে না।
এটি নির্দিষ্ট কিছু জিনিস সীমাবদ্ধ করে। উদাহরণস্বরূপ, foo
সিরিয়ালযুক্ত কোড সহ সন্ধান করা যেতে পারে, যখন l
না পারে:
>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>:
attribute lookup <lambda> on __main__ failed
আমরা foo
ঠিক দেখতে পারি - কারণ এটি নিজের নামটি জানে:
>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>
ল্যাম্বডাসের কোনও টিকা নেই এবং কোনও ডাস্ট্রিং নেই
মূলত, ল্যাম্বডাস নথিভুক্ত হয় না। foo
আরও নথিভুক্ত হতে পুনরায় লিখুন :
def foo() -> int:
"""a nullary function, returns 0 every time"""
return 0
এখন, foo এর ডকুমেন্টেশন রয়েছে:
>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:
foo() -> int
a nullary function, returns 0 every time
যদিও ল্যাম্বডাসকে একই তথ্য দেওয়ার মতো ব্যবস্থা আমাদের নেই:
>>> help(l)
Help on function <lambda> in module __main__:
<lambda> lambda (...)
তবে আমরা এগুলিকে হ্যাক করতে পারি:
>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:
<lambda> lambda ) -> in
nullary -> 0
তবে সাহায্যের আউটপুট জগাখিচুড়ি করতে গিয়ে কিছু সমস্যা আছে probably
লাম্বদাস কেবল একটি অভিব্যক্তি ফিরিয়ে দিতে পারে
লাম্বদাস জটিল বিবৃতি, কেবলমাত্র প্রকাশের পক্ষে ফিরে আসতে পারে না।
>>> lambda: if True: 0
File "<stdin>", line 1
lambda: if True: 0
^
SyntaxError: invalid syntax
এক্সপ্রেশন স্বীকার করে নাও বরং জটিল হতে পারে এবং আপনি খুব চেষ্টা করলে সম্ভবত একটি ল্যাম্বডা দিয়ে এটি সম্পাদন করতে পারেন, তবে যুক্ত জটিলতা স্পষ্ট কোড লেখার জন্য আরও ক্ষতির কারণ।
আমরা স্পষ্টতা এবং রক্ষণাবেক্ষণের জন্য পাইথন ব্যবহার করি। ল্যাম্বডাসের অতিরিক্ত ব্যবহার তার বিরুদ্ধে কাজ করতে পারে।
শুধুমাত্র lambdas জন্য গোলমালে: একটি একক এক্সপ্রেশনে তৈরি করা যেতে পারে
এটিই সম্ভাব্য upর্ধ্বমুখী। যেহেতু আপনি একটি এক্সপ্রেশন দিয়ে ল্যাম্বড তৈরি করতে পারেন, আপনি এটি কোনও ফাংশন কলের অভ্যন্তরে তৈরি করতে পারেন।
কোনও ফাংশন কলের অভ্যন্তরে একটি ফাংশন তৈরি করা (সস্তার) নামের অনুসন্ধান বনাম অন্য কোথাও তৈরি হওয়া এড়িয়ে চলে।
তবে পাইথন যেহেতু কঠোরভাবে মূল্যায়ন করা হয়েছে, নাম অনুসন্ধান এড়ানো বাদ দিয়ে অন্য কোনও কর্মক্ষমতা অর্জন করতে পারে না।
খুব সাধারণ অভিব্যক্তির জন্য, আমি একটি ল্যাম্বডা বেছে নিতে পারি।
আমি ইন্টারেক্টিভ পাইথন করার সময় ল্যাম্বডাস ব্যবহার করার ঝোঁক রাখি, যখন কেউ কখন করবে তখন একাধিক লাইন এড়াতে। আমি যখন কল করার সময় কোনও কনস্ট্রাক্টরের সাথে যুক্তিতে পাস করতে চাই তখন আমি নিম্নলিখিত ধরণের কোড ফর্ম্যাটটি ব্যবহার করি timeit.repeat
:
import timeit
def return_nullary_lambda(return_value=0):
return lambda: return_value
def return_nullary_function(return_value=0):
def nullary_fn():
return return_value
return nullary_fn
এবং এখন:
>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304
আমি বিশ্বাস করি উপরের সামান্য সময়ের পার্থক্যটি নাম অনুসন্ধানের জন্য দায়ী করা যেতে পারে return_nullary_function
- মনে রাখবেন যে এটি খুব নগন্য।
উপসংহার
লাম্বডাস অনানুষ্ঠানিক পরিস্থিতিতে যেখানে আপনি একক দৃষ্টিকোণ করার পক্ষে কোডের লাইনকে ন্যূনতম করতে চান সেখানে ভাল।
ল্যাম্বডাস আরও আনুষ্ঠানিক পরিস্থিতিতে খারাপ যেখানে আপনার কোডগুলির সম্পাদকদের যারা পরে আসবেন তাদের স্পষ্টতা দরকার, বিশেষত ক্ষেত্রে যেখানে তারা অ-তুচ্ছ হয়।
আমরা জানি আমাদের জিনিসগুলিকে ভাল নাম দেওয়ার কথা রয়েছে। যখন বস্তুর হয়েছে কীভাবে আমরা তা করতে পারেন কোন নাম?
এই সমস্ত কারণে, আমি সাধারণত এর def
পরিবর্তে ফাংশন তৈরি করতে পছন্দ করি lambda
।
lambda
, তবে আমি একমত নই যে এটি "খুব বিরল", মূল ফাংশনsorted
বাitertools.groupby
ইত্যাদির জন্য এটি সাধারণ বিষয় , যেমনsorted(['a1', 'b0'], key= lambda x: int(x[1]))