আমাদের কি কোনও শর্তে অ্যাসাইনমেন্ট থাকতে পারে?


92

একটি শর্তে অ্যাসাইনমেন্ট পাওয়া সম্ভব?

প্রাক্তন জন্য।

if (a=some_func()):
    # Use a

যে দুটি প্রশ্নের একই উত্তর রয়েছে তার মানে এই নয় যে সেগুলি সদৃশ। নিজেকে উত্তর দেওয়ার জন্য তুচ্ছ, কিন্তু তর্কটি দেখার জন্য তুচ্ছ নয় বা যদি কোনও উপায় আছে।
মেহমেট

উত্তর:


111

কেন চেষ্টা করে দেখুন না?

>>> def some_func():
...   return 2
... 
>>> a = 2
>>> if (a = some_func()):
  File "<stdin>", line 1
    if (a = some_func()):
          ^
SyntaxError: invalid syntax
>>> 

সুতরাং, না।

আপডেট: পাইথন ৩.৮ এ এটি (বিভিন্ন সিনট্যাক্স সহ) সম্ভব


35
এটিকে ইচ্ছাকৃতভাবে গাইডো, দানশীল পাইথন একনায়ক হিসাবে নিষিদ্ধ করা হয়েছে, এগুলি দরকারীগুলির চেয়ে অপ্রয়োজনীয় এবং আরও বিভ্রান্তিকর বলে মনে করে। পোস্ট-ইনক্রিমেন্ট বা প্রাক-ইনক্রিমেন্ট অপারেটর (++) নেই এমন একই কারণ।
ম্যাট বোহেম

4
তিনি যোগে অনুমতি করেনি উদ্দীপ্ত assigment 2.0 কারণ x = x + 1অতিরিক্ত লুকআপ সময়ের প্রয়োজন যখন x += 1কিছুটা দ্রুততর ছিল, কিন্তু আমি নিশ্চিত নই সে এমনকি করছেন ভালো লাগে নি যে অনেক। :-)
ওয়েস্কি

আশা করি, শিগগিরই এটি সম্ভব হয়ে উঠবে। পাইথনটি বিকশিত হতে কেবল ধীর
নিক ও'লাই

4
"কেন এটি চেষ্টা করে দেখবেন না" - কারণ সিনট্যাক্স কী হতে পারে কে জানে? হয়তো ওপি চেষ্টা করেছিল এবং এটি কাজ করে নি, তবে এর অর্থ এই নয় যে সিনট্যাক্সটি আলাদা নয়, বা এটি করার মতো কোনও উপায় নেই যা উদ্দেশ্য নয়
লেভি এইচ

57

আপডেট - মূল উত্তরটি নীচের দিকে

পাইথন 3.8 পিইপি 572 এনে দেবে

অ্যাবস্ট্রাক্ট
এটি স্বরলিপিটি NAME: = expr ব্যবহার করে একটি অভিব্যক্তির মধ্যে ভেরিয়েবলগুলিকে নির্ধারণের জন্য একটি উপায় তৈরি করার প্রস্তাব। একটি নতুন ব্যতিক্রম, টার্গেটস্কোপ এরর যুক্ত করা হয়েছে এবং মূল্যায়নের ক্রমটিতে একটি পরিবর্তন রয়েছে।

https://lwn.net/Articles/757713/

"পিইপি 572 জগাখিচুড়ি" হলেন 2018 এর পাইথন ল্যাঙ্গুয়েজ সামিটের অধিবেশনটির বিষয় যা ছিল জীবনের জন্য দানশীল স্বৈরশাসকের নেতৃত্বে (বিডিএফএল) গাইডো ভ্যান রসম। পিইপি 572 ভাষাতে অ্যাসাইনমেন্ট এক্সপ্রেশন (বা "ইনলাইন অ্যাসাইনমেন্ট") যুক্ত করার চেষ্টা করে তবে পাইথন-ডেড মেইলিং লিস্টে একাধিক বিশাল থ্রেডের উপর এটি দীর্ঘায়িত আলোচনা দেখেছিল - পাইথন-আইডিয়াগুলিতে একাধিক রাউন্ড পরেও। এই থ্রেডগুলি প্রায়শই বিতর্কিত ছিল এবং স্পষ্টতই এ জাতীয় পয়েন্টে বেশিরভাগ ক্ষেত্রে ছিল যেখানে অনেকে সম্ভবত এগুলি তৈরি করেছিলেন। শীর্ষ সম্মেলনে ভ্যান রসুম বৈশিষ্ট্য প্রস্তাবটির একটি ওভারভিউ দিয়েছিলেন, যা তিনি গ্রহণ করার দিকে ঝুঁকির মনে হলেও ভবিষ্যতে এই ধরণের থ্রেড বিস্ফোরণ এড়াতে কীভাবে সে আলোচনা করতে চেয়েছিল।

https://www.python.org/dev/peps/pep-0572/#exferences-from-the-python-standard-library

পাইথন স্ট্যান্ডার্ড লাইব্রেরির উদাহরণ

সাইট.py env_base কেবলমাত্র এই লাইনে ব্যবহৃত হয়, যদি তার অ্যাসাইনমেন্টটি ব্লকের "শিরোলেখ" হিসাবে সরানো হয় তবে এটির উপর এটি স্থাপন করে।

বর্তমান:

env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
    return env_base

উন্নত:

if env_base := os.environ.get("PYTHONUSERBASE", None):
    return env_base
_pydecimal.py

নেস্টেড এড়িয়ে চলুন এবং একটি ইনডেন্টেশন স্তর সরান।

বর্তমান:

if self._is_special:
    ans = self._check_nans(context=context)
    if ans:
        return ans

উন্নত:

if self._is_special and (ans := self._check_nans(context=context)):
    return ans

copy.py কোডটি আরও নিয়মিত দেখাচ্ছে এবং যদি একাধিক নেস্টেড এড়ায়। (এই উদাহরণের উত্সের জন্য পরিশিষ্ট এ দেখুন))

বর্তমান:

reductor = dispatch_table.get(cls)
if reductor:
    rv = reductor(x)
else:
    reductor = getattr(x, "__reduce_ex__", None)
    if reductor:
        rv = reductor(4)
    else:
        reductor = getattr(x, "__reduce__", None)
        if reductor:
            rv = reductor()
        else:
            raise Error(
                "un(deep)copyable object of type %s" % cls)

উন্নত:

if reductor := dispatch_table.get(cls):
    rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
    rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
    rv = reductor()
else:
    raise Error("un(deep)copyable object of type %s" % cls)
datetime.py

tz কেবলমাত্র s + = tz এর জন্য ব্যবহৃত হয়, যদি তার ক্ষেত্রটি প্রদর্শন করতে সহায়তা করে তবে এটির ভিতরে তার অ্যাসাইনমেন্টটি সরিয়ে নেওয়া হয়।

বর্তমান:

s = _format_time(self._hour, self._minute,
                 self._second, self._microsecond,
                 timespec)
tz = self._tzstr()
if tz:
    s += tz
return s

উন্নত:

s = _format_time(self._hour, self._minute,
                 self._second, self._microsecond,
                 timespec)
if tz := self._tzstr():
    s += tz
return s

sysconfig.py কিছুক্ষণের মধ্যে fp.readline () কল করা এবং যদি লাইনে কোডটি আরও কমপ্যাক্ট করে তোলে তবে ম্যাপ () কে কল করুন

এটি বোঝা শক্ত করে তোলে।

বর্তমান:

while True:
    line = fp.readline()
    if not line:
        break
    m = define_rx.match(line)
    if m:
        n, v = m.group(1, 2)
        try:
            v = int(v)
        except ValueError:
            pass
        vars[n] = v
    else:
        m = undef_rx.match(line)
        if m:
            vars[m.group(1)] = 0

উন্নত:

while line := fp.readline():
    if m := define_rx.match(line):
        n, v = m.group(1, 2)
        try:
            v = int(v)
        except ValueError:
            pass
        vars[n] = v
    elif m := undef_rx.match(line):
        vars[m.group(1)] = 0

সরলকরণ তালিকা অনুধাবন একটি তালিকা বোধ শর্তটি ক্যাপচারের মাধ্যমে দক্ষতার সাথে মানচিত্র এবং ফিল্টার করতে পারে:

results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]

একইভাবে, প্রথম ব্যবহারের উপর একটি নাম দিয়ে, একটি মূল এক্সপ্রেশনটিকে পুনরায় ব্যবহার করা যেতে পারে:

stuff = [[y := f(x), x/y] for x in range(5)]

নোট করুন যে উভয় ক্ষেত্রেই ভেরিয়েবল y সংযুক্ত সুযোগে আবদ্ধ (যেমন ফলাফল বা স্টাফ হিসাবে একই স্তরের)।

কন্ডিশনের মানগুলি ক্যাপচার করা অ্যাসাইনমেন্ট এক্সপ্রেশনগুলি যদি কোনও বা বিবৃতি দেওয়ার সময় শিরোনামে ভাল প্রভাবের জন্য ব্যবহৃত হয়:

# Loop-and-a-half
while (command := input("> ")) != "quit":
    print("You entered:", command)

# Capturing regular expression match objects
# See, for instance, Lib/pydoc.py, which uses a multiline spelling
# of this effect
if match := re.search(pat, text):
    print("Found:", match.group(0))
# The same syntax chains nicely into 'elif' statements, unlike the
# equivalent using assignment statements.
elif match := re.search(otherpat, text):
    print("Alternate found:", match.group(0))
elif match := re.search(third, text):
    print("Fallback found:", match.group(0))

# Reading socket data until an empty string is returned
while data := sock.recv(8192):
    print("Received data:", data)

বিশেষত ওয়েল লুপের সাহায্যে এটি অসীম লুপ, একটি অ্যাসাইনমেন্ট এবং শর্ত থাকা প্রয়োজন দূর করতে পারে। এটি একটি লুপের মধ্যে একটি মসৃণ সমান্তরাল তৈরি করে যা কেবল এটির শর্ত হিসাবে একটি ফাংশন কল ব্যবহার করে এবং এটি যা এটি তার শর্ত হিসাবে ব্যবহার করে তবে প্রকৃত মানও ব্যবহার করে।

কাঁটাচামচ নিম্ন-স্তরের ইউনিক্স বিশ্ব থেকে একটি উদাহরণ:

if pid := os.fork():
    # Parent code
else:
    # Child code

আসল উত্তর

http://docs.python.org/tutorial/datastructures.html

দ্রষ্টব্য যে পাইথনে সি এর বিপরীতে অ্যাসাইনমেন্টটি এক্সপ্রেশনের অভ্যন্তরে ঘটতে পারে না। সি প্রোগ্রামাররা এটি সম্পর্কে তুচ্ছ করতে পারে তবে এটি সি প্রোগ্রামগুলিতে যে সাধারণ শ্রেণিবদ্ধ সমস্যাগুলির মুখোমুখি হয় তা এড়িয়ে চলে: টাইপিং = টাইপ = একটি অভিব্যক্তিতে যখন == উদ্দেশ্য ছিল।

আরও দেখুন:

http://effbot.org/pyfaq/why-can-ti-use-an-assignment-in-an-expression.htm


আমি এই উত্তর মত কারণ এটা আসলে তুলে ধরে কেন এই ধরনের একটি "বৈশিষ্ট্য" আছে ইচ্ছাকৃতভাবে পাইথন বাইরে রেখে দেওয়া হতে পারে। শিক্ষানবিসের প্রোগ্রামিং শেখানোর সময়, আমি if (foo = 'bar')এর মান পরীক্ষা করার সময় অনেককে এই ভুল করতে দেখেছি foo
জোনাথন ক্রস

4
@ জোনাথনক্রস, এই "বৈশিষ্ট্য "টি আসলে ৩.৮-এ যুক্ত হতে চলেছে। এটি যতটা কম স্পষ্টভাবে ব্যবহার করা সম্ভব নয় - তবে কমপক্ষে এটি কোনও সমতল নয়=
জন লা রুই

@ জনলআরউই: উদাহরণগুলি দেখে আমার ধারণা স্পট-অন ছিল "যতটা করা উচিত ততটুকু ব্যবহার করা সম্ভব নয়"; ~ 10 উদাহরণগুলির মধ্যে, আমি দেখতে পেয়েছি যে কেবলমাত্র দুটি জন কোডটি উন্নত করে। (যথা কিছুক্ষণের মধ্যে একক অভিব্যক্তি হিসাবে, লাইনটি অনুলিপি করা বা শরীরে লুপের অবস্থা না হওয়া বা বাসা
বাঁধতে বাঁচতে এলিফ

39

নাহ, বিডিএফএল সেই বৈশিষ্ট্যটি পছন্দ করে নি।

আমি যেখান থেকে বসেছি, পাইপোনকে যতটা সহজ হতে পারে সহজ হিসাবে রাখতে "লাইভেরভ্যালেন্ট ডিক্টেটর অফ লাইফ" গুইডো ভ্যান রসম কঠোর লড়াই করেছে এবং আমরা যে সিদ্ধান্ত নিয়েছি তার কিছুটা আমরা দমন করতে পারি - আমি পছন্দ করতাম তিনি 'না' বলেছিলেন 'প্রায়শই.কিন্তু সত্য যে পাইথন ডিজাইন করার জন্য একটি কমিটি হয়নি, বরং পরিবর্তে একটি নির্ভরযোগ্য "পরামর্শদাতা বোর্ড" মূলত যোগ্যতার ভিত্তিতে, একজন ডিজাইনারের সংবেদনশীলতার মাধ্যমে ফিল্টার করে , একটি সুন্দর ভাষার একটি নরক তৈরি করেছে, আইএমএইচও।


15
সরল? এই বৈশিষ্ট্যটি আমার কোডের বেশ কয়েকটি সহজতর করতে পারে কারণ এটি এটিকে আরও কমপ্যাক্ট এবং আরও বেশি পাঠযোগ্য। এখন আমার দুটি লাইন দরকার যেখানে আমার একটি দরকার ছিল। পাইথন অন্যান্য প্রোগ্রামিং ভাষার বহু বছরের জন্য (এবং প্রায়শই খুব ভাল কারণে) যে বৈশিষ্ট্যগুলি প্রত্যাখ্যান করেছিল তা আমি কখনই পাইনি। বিশেষত আমরা এখানে যে বৈশিষ্ট্যটির কথা বলছি তা খুব কার্যকর।
রেজিস

6
কম কোড সর্বদা সহজ বা মোড়ের পাঠযোগ্য নয়। উদাহরণস্বরূপ একটি পুনরাবৃত্তি ফাংশন নিন। এটি লুপ সমতুল্য প্রায়শই বেশি পঠনযোগ্য।
এফএমএফ

4
আমি এর সি সংস্করণটি পছন্দ করি না, তবে আমি if letইস্ট এলিফ চেইন থাকাকালীন আমি মরিচাছির মতো কিছু পাওয়া মিস করি তবে প্রতিটি ক্ষেত্রে শর্তের মান সংরক্ষণ এবং ব্যবহার করা দরকার।
থায়নে

4
আমি এখন যে কোডটি লিখছি তা বলতে হবে (যে কারণে আমি এই সমস্যাটি অনুসন্ধান করেছি) এটি এই বৈশিষ্ট্যটি ব্যতীত খারাপ g ব্যবহারের পরিবর্তে যদি আরও প্রচুর ifs অনুসরণ করে তবে আমার অন্যটির নীচে থাকলে পরবর্তী ইনডেন্ট করা দরকার।
মাইককুলস 24:38

17

আমার এই পুরানো রেসিপিটি প্রত্যক্ষভাবে নয়, তবে রেসিপিটি অনুসারে শব্দার্থ সমতুল্য তৈরি করা সহজ, উদাহরণস্বরূপ আপনার যদি কোনও সি-কোডেড রেফারেন্স অ্যালগরিদম থেকে সরাসরি প্রতিলিপি তৈরি করতে হয় (অবশ্যই আরও মূর্তিযুক্ত পাইথনকে রিফ্যাক্টর করার আগে; -)। অর্থাৎ:

class DataHolder(object):
    def __init__(self, value=None): self.value = value
    def set(self, value): self.value = value; return value
    def get(self): return self.value

data = DataHolder()

while data.set(somefunc()):
  a = data.get()
  # use a

বিটিডাব্লু, আপনার নির্দিষ্ট ক্ষেত্রেটির জন্য একটি অত্যন্ত মূর্তিমানিক পাইথোনিক ফর্ম, যদি আপনি ঠিক জানেন যে somefuncমিথ্যা মানটি (যেমন 0) ফিরিয়ে দেয় তখন ফালিশ মানটি কী ফিরে আসতে পারে ,

for a in iter(somefunc, 0):
  # use a

সুতরাং এই নির্দিষ্ট ক্ষেত্রে রিফ্যাক্টরিং বেশ সহজ হবে ;-)।

প্রত্যাবর্তন হতে পারে যদি কোনো falsish মান ধরনের (0, None, '', ...), এক সম্ভাবনা আছে:

import itertools

for a in itertools.takewhile(lambda x: x, iter(somefunc, object())):
    # use a

তবে আপনি একটি সাধারণ কাস্টম জেনারেটর পছন্দ করতে পারেন:

def getwhile(func, *a, **k):
    while True:
      x = func(*a, **k)
      if not x: break
      yield x

for a in getwhile(somefunc):
    # use a

আমি পারলে দু'বার এটিকে ভোট দিতাম। এটি সেই সময়ের জন্য দুর্দান্ত সমাধান যখন এর মতো কিছু সত্যই প্রয়োজন হয়। আমি আপনার সমাধানটিকে একটি রেইজেক্স ম্যাচার ক্লাসে রূপান্তরিত করেছি, যা একবার ইনস্ট্যান্ট করা হয় এবং তারপরে ম্যাচটি পুনরুদ্ধার করতে if স্টেটমেন্ট এবং .result () এর শরীরের ভিতরে ব্যবহার করা হয়। ধন্যবাদ! :)
টেকিন

16

হ্যাঁ, তবে কেবল পাইথন থেকে 3.8 এবং এর পরে।

পিইপি 572 অ্যাসাইনমেন্ট এক্সপ্রেশনগুলির প্রস্তাব দেয় এবং ইতিমধ্যে গৃহীত হয়েছে।

পিইপি-এর সিনট্যাক্স এবং শব্দার্থবিজ্ঞানের অংশ উদ্ধৃত করা :

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    # Do something with match

# A loop that can't be trivially rewritten using 2-arg iter()
while chunk := file.read(8192):
   process(chunk)

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]

আপনার নির্দিষ্ট ক্ষেত্রে, আপনি লিখতে সক্ষম হবেন

if a := some_func():
    # Use a

5

পাইথনে অ্যাসাইনমেন্ট একটি বিবৃতি, কোনও অভিব্যক্তি নয়।


এবং গাইডোর এটি অন্য কোনও উপায়ে থাকত না।
মার্ক র্যানসম

4
নিবন্ধন করুন ডান .. দীর্ঘশ্বাস।
স্টিফেনবোশ

@ জাভাদ্ব্বা লোকটি তার ভুল হওয়ার চেয়ে অনেক বেশি সময় ধরে ডান হয়েছে। আমি প্রশংসা করি যে দৃষ্টিভঙ্গির দায়িত্বে থাকা একক ব্যক্তি কমিটির নকশার চেয়ে অনেক বেশি সুসংহত কৌশল অর্জন করে; আমি সি ++ এর সাথে তুলনা করতে এবং তার বিপরীতে করতে পারি যা আমার প্রধান রুটি এবং মাখন।
মার্ক

আমি রুবি এবং স্কালা উভয়ই অনুভব করি (বনাম বিভিন্ন ভাষা) পাইথনের চেয়ে এটি উল্লেখযোগ্যভাবে আরও সঠিকভাবে পেয়েছে: তবে যে কোনও ক্ষেত্রে এখানে স্থান নেই ..
স্টিফেনবোশ

4

পাইথন ৩.৮ নতুন বৈশিষ্ট্যের জন্য ধন্যবাদ এই সংস্করণ থেকে এ জাতীয় কাজ করা সম্ভব হবে, যদিও এটি =অ্যাডা-এর মতো অ্যাসাইনমেন্ট অপারেটর ব্যবহার না করে :=। দস্তাবেজ থেকে উদাহরণ:

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    # Do something with match

2

আপনার জন্য কার্য সম্পাদনের জন্য আপনি কোনও ফাংশন সংজ্ঞায়িত করতে পারেন:

def assign(name, value):
    import inspect
    frame = inspect.currentframe()
    try:
        locals_ = frame.f_back.f_locals
    finally:
        del frame 
    locals_[name] = value
    return value

if assign('test', 0):
    print("first", test)
elif assign('xyz', 123):
    print("second", xyz)

1

শর্তে অ্যাসাইনমেন্ট অবৈধ হওয়ার একটি কারণ হ'ল ভুল করা এবং সত্য বা মিথ্যা নির্ধারণ করা সহজ:

some_variable = 5

# This does not work
# if True = some_variable:
#   do_something()

# This only works in Python 2.x
True = some_variable

print True  # returns 5

পাইথনে 3 সত্য এবং মিথ্যা কীওয়ার্ড, সুতরাং আর কোনও ঝুঁকি নেই।


4
[১1১]: l_empty == [] আউট [161]: সত্যে [162]: [] == [] আউট [162]: সত্য আমি এর কারণ মনে করি না
আগ্নেয়গিরি

খুব নিশ্চিত যে বেশিরভাগ লোক == Trueযেভাবেই ডানদিকে রাখে।
নম্বরমানিয়াক

1

অ্যাসাইনমেন্ট অপারেটর - ওয়ালরাস অপারেটর হিসাবে অনানুষ্ঠানিকভাবে পরিচিত - পিইপি 572 -এ 28-ফেব্রুয়ারী 2018-এ তৈরি হয়েছিল ।

সম্পূর্ণতার জন্য, আমি প্রাসঙ্গিক অংশগুলি পোস্ট করব যাতে আপনি 3.7 এবং 3.8 এর মধ্যে পার্থক্য তুলনা করতে পারেন:

3.7
---
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
test: or_test ['if' or_test 'else' test] | lambdef
test_nocond: or_test | lambdef_nocond
lambdef: 'lambda' [varargslist] ':' test
lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*

3.8
---
if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
namedexpr_test: test [':=' test]                         <---- WALRUS OPERATOR!!!
test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.