:=
পাইথন ৩.৮-তে যোগ করা অ্যাসাইনমেন্ট এক্সপ্রেশন অপারেটর লাম্বদা এক্সপ্রেশনগুলির ভিতরে অ্যাসাইনমেন্ট সমর্থন করে। এই অপারেটরটি সিন্থেটিক কারণে শুধুমাত্র একটি প্রথম বন্ধনীযুক্ত (...)
, বন্ধনীযুক্ত [...]
বা ব্রেসড {...}
এক্সপ্রেশনের মধ্যে উপস্থিত হতে পারে । উদাহরণস্বরূপ, আমরা নিম্নলিখিত লিখতে সক্ষম হবে:
import sys
say_hello = lambda: (
message := "Hello world",
sys.stdout.write(message + "\n")
)[-1]
say_hello()
পাইথন 2 এ, তালিকা বোধের পার্শ্ব প্রতিক্রিয়া হিসাবে স্থানীয় কার্য সম্পাদন করা সম্ভব হয়েছিল।
import sys
say_hello = lambda: (
[None for message in ["Hello world"]],
sys.stdout.write(message + "\n")
)[-1]
say_hello()
যাইহোক, আপনার উদাহরণগুলিতে flag
এর মধ্যে দুটিও ব্যবহার করা সম্ভব নয় কারণ আপনার পরিবর্তনশীল কোনও বাহ্যিক স্কোপে রয়েছে, lambda
এর স্কোপ নয়। এই না হবে তা নয় lambda
, এটা পাইথন 2. পাইথন সাধারণ আচরণের জন্য 3 আপনার সাথে এই কাছাকাছি পেতে দেয় এর nonlocal
এর শব্দ ভিতরে def
গুলি কিন্তু nonlocal
ভিতরে ব্যবহার করা যাবে না lambda
সে।
এখানে একটি কার্যনির্বাহ রয়েছে (নীচে দেখুন), তবে আমরা যখন বিষয়টিতে রয়েছি ...
কিছু ক্ষেত্রে আপনি এটির অভ্যন্তরে সমস্ত কিছু করতে এটি ব্যবহার করতে পারেন lambda
:
(lambda: [
['def'
for sys in [__import__('sys')]
for math in [__import__('math')]
for sub in [lambda *vals: None]
for fun in [lambda *vals: vals[-1]]
for echo in [lambda *vals: sub(
sys.stdout.write(u" ".join(map(unicode, vals)) + u"\n"))]
for Cylinder in [type('Cylinder', (object,), dict(
__init__ = lambda self, radius, height: sub(
setattr(self, 'radius', radius),
setattr(self, 'height', height)),
volume = property(lambda self: fun(
['def' for top_area in [math.pi * self.radius ** 2]],
self.height * top_area))))]
for main in [lambda: sub(
['loop' for factor in [1, 2, 3] if sub(
['def'
for my_radius, my_height in [[10 * factor, 20 * factor]]
for my_cylinder in [Cylinder(my_radius, my_height)]],
echo(u"A cylinder with a radius of %.1fcm and a height "
u"of %.1fcm has a volume of %.1fcm³."
% (my_radius, my_height, my_cylinder.volume)))])]],
main()])()
10.0 সেমি ব্যাসার্ধ এবং 20.0 সেমি উচ্চতা সহ একটি সিলিন্ডারের আয়তন 6283.2 সেমি³ ³
20.0 সেমি ব্যাসার্ধ এবং 40.0 সেমি উচ্চতা সহ একটি সিলিন্ডারের আয়তন 50265.5 সেমি³ ³
30.0 সেমি ব্যাসার্ধ এবং 60.0 সেমি উচ্চতা সহ একটি সিলিন্ডারের আয়তন 169646.0 সেমি³ has
দয়া করে না।
... আপনার আসল উদাহরণে ফিরে যান: আপনি flag
বাহ্যিক স্কোপে ভেরিয়েবলের অ্যাসাইনমেন্টগুলি সম্পাদন করতে না পারলেও আপনি পূর্বনির্ধারিত মানটি সংশোধন করতে ফাংশন ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, flag
এমন কোনও বস্তু হতে পারে যার .value
ব্যবহার করে আমরা সেট করেছি setattr
:
flag = Object(value=True)
input = [Object(name=''), Object(name='fake_name'), Object(name='')]
output = filter(lambda o: [
flag.value or bool(o.name),
setattr(flag, 'value', flag.value and bool(o.name))
][0], input)
[Object(name=''), Object(name='fake_name')]
আমরা উপরের থিমটি ফিট করতে চাইলে আমরা এর পরিবর্তে একটি তালিকা উপলব্ধি ব্যবহার করতে পারি setattr
:
[None for flag.value in [bool(o.name)]]
তবে সত্যই, গুরুতর কোডে আপনার যদি সর্বদা lambda
বাইরের অ্যাসাইনমেন্টটি করাতে চলেছে তবে আপনার পরিবর্তে নিয়মিত ফাংশন সংজ্ঞাটি ব্যবহার করা উচিত ।
flag = Object(value=True)
def not_empty_except_first(o):
result = flag.value or bool(o.name)
flag.value = flag.value and bool(o.name)
return result
input = [Object(name=""), Object(name="fake_name"), Object(name="")]
output = filter(not_empty_except_first, input)