এই প্রশ্নটি "বিখ্যাত" এবং "সুস্পষ্ট" পাইথন সিনট্যাক্সের খুব দুর্গন্ধযুক্ত অংশকে স্পর্শ করে - যা অগ্রাধিকার, ল্যাম্বডা বা তালিকা বোধগম্যতার জন্য লাগে।
আমি মনে করি না যে ওপির উদ্দেশ্যটি 0 থেকে 9 পর্যন্ত স্কোয়ারগুলির একটি তালিকা তৈরি করা ছিল যদি এটি হয় তবে আমরা আরও বেশি সমাধান দিতে পারতাম:
squares = []
for x in range(10): squares.append(x*x)
- এটি হ'ল অপরিহার্য সিনট্যাক্সের ভাল উপায়।
তবে এটি বিন্দু নয়। মোদ্দা কথাটি হ'ল ডাব্লু (হাই) টিএফ কি এই অস্পষ্ট অভিব্যক্তিটি এতটা পাল্টা স্বজ্ঞাত? এবং আমি আপনার শেষে একটি বোকামি মামলা আছে, তাই আমার উত্তর খুব তাড়াতাড়ি খারিজ করবেন না (আমার কাছে এটি একটি কাজের সাক্ষাত্কারে ছিল)।
সুতরাং, ওপির উপলব্ধি ল্যাম্বডাসের একটি তালিকা ফিরিয়ে দিয়েছে:
[(lambda x: x*x) for x in range(10)]
স্কোয়ারিং ফাংশনের এটি অবশ্যই 10 টি বিভিন্ন অনুলিপি, দেখুন:
>>> [lambda x: x*x for _ in range(3)]
[<function <lambda> at 0x00000000023AD438>, <function <lambda> at 0x00000000023AD4A8>, <function <lambda> at 0x00000000023AD3C8>]
ল্যাম্বডাসের মেমরি ঠিকানাগুলি নোট করুন - এগুলি সমস্ত আলাদা!
আপনার কাছে অবশ্যই এই এক্সপ্রেশনটির আরও "অনুকূল" (হাঃ) সংস্করণ থাকতে পারে:
>>> [lambda x: x*x] * 3
[<function <lambda> at 0x00000000023AD2E8>, <function <lambda> at 0x00000000023AD2E8>, <function <lambda> at 0x00000000023AD2E8>]
দেখা? 3 বার একই লাম্বদা।
দয়া করে মনে রাখবেন, আমি ভেরিয়েবল _হিসাবে ব্যবহার করেছি for। এটা দিয়ে কিছুই করার আছে xএ lambda(এটা আভিধানিক ঢেকে দিল করা হয়!)। এটা নাও?
আমি আলোচনাটি বাদ দিচ্ছি, সিনট্যাক্সের অগ্রাধিকারটি কেন নয়, এর অর্থ এই:
[lambda x: (x*x for x in range(10))]
যা হতে পারে :,[[0, 1, 4, ..., 81]] বা [(0, 1, 4, ..., 81)], বা যা আমি সবচেয়ে যুক্তিসঙ্গত বলে মনে করি এটিlist 1 টি উপাদানগুলির একটি হতে পারে - generatorমানগুলি ফিরিয়ে দেয়। এটি কেবল ঘটনা নয়, ভাষা এইভাবে কাজ করে না।
তবে কি, যদি ...
আপনি যদি forভেরিয়েবলকে ছায়া না ফেলে এবং এটি আপনার ব্যবহার করে থাকেন তবে কি lambda???
ঠিক আছে, তাহলে বাজে ঘটনা ঘটে। এটা দেখ:
[lambda x: x * i for i in range(4)]
অবশ্যই এই উপায়:
[(lambda x: x * i) for i in range(4)]
তবে এর অর্থ এই নয়:
[(lambda x: x * 0), (lambda x: x * 1), ... (lambda x: x * 3)]
এ তো শুধুই পাগল!
তালিকা অনুধাবন ল্যাম্বডাস এই বোধগম্যতার পরিধি বন্ধ করে দেয়। একটি লেজিকাল ক্লোজার, সুতরাং তারা iরেফারেন্সের মাধ্যমে রেফারেন্স দেয় এবং মূল্যায়ন করার সময় এর মান হয় না!
সুতরাং, এই অভিব্যক্তি:
[(lambda x: x * i) for i in range(4)]
মোটামুটি এর জন্য মূল্যবান:
[(lambda x: x * 3), (lambda x: x * 3), ... (lambda x: x * 3)]
আমি নিশ্চিত যে পাইথন ডিকম্পিলার (যার অর্থ আমি উদাহরণস্বরূপ disমডিউল) ব্যবহার করে এখানে আরও দেখতে পাব , তবে পাইথন-ভিএম-অজোনস্টিক আলোচনার জন্য এটি যথেষ্ট। চাকরির ইন্টারভিউ প্রশ্নের জন্য এত কিছু।
এখন, কীভাবে একটি listগুণক ল্যাম্বডাস তৈরি করবেন, যা ক্রমাগত সংখ্যার দ্বারা গুণিত হয়? ঠিক আছে, অনুরূপভাবে গৃহীত উত্তরের মতো, আমাদের iএটির সাথে অন্যকে আবৃত করে সরাসরি টাইটি ভাঙতে হবে lambda, যা তালিকার বোঝাপড়ার এক্সপ্রেশনটির ভিতরে ডাকা হচ্ছে :
আগে:
>>> a = [(lambda x: x * i) for i in (1, 2)]
>>> a[1](1)
2
>>> a[0](1)
2
পরে:
>>> a = [(lambda y: (lambda x: y * x))(i) for i in (1, 2)]
>>> a[1](1)
2
>>> a[0](1)
1
(আমার কাছে বাইরের ল্যাম্বডা ভেরিয়েবলটিও ছিল = i, তবে আমি স্থির করেছি যে এটিই আরও পরিষ্কার সমাধান - আমি yএমনভাবে প্রবর্তন করেছি যাতে আমরা সকলেই দেখতে পাচ্ছি কোন ডাইনটি কোনটি)।
2019-08-30 সম্পাদনা করুন:
@ জোসোলারের একটি পরামর্শ অনুসরণ করে যা @ শেরিড্পের একটি উত্তরে উপস্থিত রয়েছে - তালিকাটি বোঝার "লুপ ভেরিয়েবল" কোনও বস্তুর অভ্যন্তরে "এম্বেড" হতে পারে - সঠিক সময়ে এটি অ্যাক্সেস করার জন্য কীটি রয়েছে। অধ্যায় "পর" অন্য এটা মোড়কে এটা আছে উপরে lambdaএবং এটি অবিলম্বে কলিং বর্তমান মান সঙ্গে i। অন্য উপায় (পড়ার জন্য কিছুটা সহজ - এটি কোনও 'ওয়াট' প্রভাব তৈরি করে না) হ'ল iকোনও partialবস্তুর অভ্যন্তরের মান সংরক্ষণ করা হয় এবং "অভ্যন্তরীণ" (মূল )টিকে lambdaএটি একটি আর্গুমেন্ট হিসাবে গ্রহণ করা হয় ( partialবস্তুটির দ্বারা সরবরাহিত সরবরাহ করে ) কল করার সময়), যেমন:
2 পরে:
>>> from functools import partial
>>> a = [partial(lambda y, x: y * x, i) for i in (1, 2)]
>>> a[0](2), a[1](2)
(2, 4)
দুর্দান্ত, তবে আপনার জন্য এখনও কিছুটা বাঁক আছে! ধরা যাক আমরা কোড রিডারে এটিকে আরও সহজ করে তুলতে চাই না, এবং নামটি দিয়ে ফ্যাক্টরটি পাস করবো (এতে কীওয়ার্ড যুক্তি হিসাবে partial)। আসুন কিছু নামকরণ করা যাক:
2.5 পরে:
>>> a = [partial(lambda coef, x: coef * x, coef=i) for i in (1, 2)]
>>> a[0](1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() got multiple values for argument 'coef'
WAT?
>>> a[0]()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'x'
অপেক্ষা করুন ... আমরা আর্গুমেন্টের সংখ্যা 1 দ্বারা পরিবর্তন করছি, এবং "খুব বেশি" থেকে "খুব কম" তে যাচ্ছি?
ওয়েল, এটা একটি বাস্তব WAT নয়, যখন আমরা পাস coefকরতে partialএই ভাবে, এটা একটি শব্দ যুক্তি হয়ে তাই এটি অবস্থানগত পরে আসা আবশ্যক x, যুক্তি যেমন:
3 পরে:
>>> a = [partial(lambda x, coef: coef * x, coef=i) for i in (1, 2)]
>>> a[0](2), a[1](2)
(2, 4)
আমি নেস্টেড ল্যাম্বদার চেয়ে শেষ সংস্করণটি পছন্দ করবো তবে প্রতিটি তার নিজস্ব ...
[lambda x: x*x for x in range(10)]এটি প্রথমটির চেয়ে দ্রুততর, যেহেতু এটি বাইরের লুপ ফাংশনটিকে কল করে না, বারবার চ।