সি # নাল-কোলেসিং অপারেটরের একটি পাইথনের সমতুল্য কি আছে?


301

সি # তে একটি নাল-কোয়েলসিং অপারেটর রয়েছে (যেমন লিখিত ??) যা নিয়োগের সময় সহজে (সংক্ষিপ্ত) নাল চেক করার অনুমতি দেয়:

string s = null;
var other = s ?? "some default value";

একটি অজগর সমতুল্য আছে?

আমি জানি যে আমি এটি করতে পারি:

s = None
other = s if s else "some default value"

তবে কি আরও ছোট একটি উপায় আছে (যেখানে আমার পুনরাবৃত্তি করার প্রয়োজন নেই s)?


14
??অপারেটর হিসাবে প্রস্তাব করা হয় PEP 505
200_সাক্সেস

উত্তর:


421
other = s or "some default value"

ঠিক আছে, orঅপারেটর কীভাবে কাজ করে তা অবশ্যই পরিষ্কার করা উচিত । এটি একটি বুলিয়ান অপারেটর, সুতরাং এটি বুলিয়ান প্রসঙ্গে কাজ করে। মানগুলি বুলিয়ান না হলে অপারেটরের উদ্দেশ্যে সেগুলি বুলেয়ানে রূপান্তরিত হয়।

নোট করুন যে orঅপারেটর কেবল Trueবা ফিরে আসে না False। পরিবর্তে, প্রথম অপারেন্ডটি সত্য হিসাবে মূল্যায়ন করলে এটি প্রথম অপারেন্ডকে ফেরত দেয়, এবং যদি প্রথম অপারেন্ডটি মিথ্যা হিসাবে মূল্যায়ন করে তবে এটি দ্বিতীয় অপারেন্ডকে ফিরিয়ে দেয়।

এক্ষেত্রে, বুলিয়ান রূপান্তরিত হওয়ার সময় এক্সপ্রেশনটি যদি সত্য হয় বা সত্যায় মূল্যায়ণ হয় x or yreturns অন্যথায়, এটি ফিরে আসে । বেশিরভাগ ক্ষেত্রে, এটি সি এর নাল-কোলেসিং অপারেটরের খুব একই উদ্দেশ্যে কাজ করবে তবে মনে রাখবেন:xTruey

42    or "something"    # returns 42
0     or "something"    # returns "something"
None  or "something"    # returns "something"
False or "something"    # returns "something"
""    or "something"    # returns "something"

যদি আপনি sএমন কিছু ধরে রাখার জন্য আপনার ভেরিয়েবল ব্যবহার করেন যা হয় কোনও শ্রেণীর উদাহরণ Noneহিসাবে উল্লেখ করা হয় বা (যতক্ষণ না আপনার শ্রেণি সদস্যদের সংজ্ঞা দেয় না __nonzero__()এবং __len__()), নাল-কোয়েলসিং অপারেটরের মতো একই শব্দার্থক শব্দ ব্যবহার করা নিরাপদ।

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

কিছু ভাষায় এই আচরণকে এলভিস অপারেটর হিসাবে উল্লেখ করা হয় ।


3
এটি কি একই কাজ করবে? মানে, যদি এটি sএকটি বৈধ মান হয় তবে সত্য না হয় এটি কি ভেঙে দেবে? (আমি পাইথন জানি না, সুতরাং 'সত্যবাদী' ধারণাটি প্রযোজ্য কিনা তা আমি নিশ্চিত নই।)
সিএইচও

9
সংখ্যা 0, Noneএবং খালি পাত্রে (স্ট্রিং সহ) ধ্রুবক ছাড়াও মিথ্যা হিসাবে বিবেচিত হয় False। অন্যান্য সমস্ত কিছু সত্য বলে বিবেচিত হয়। আমি বলব যে এখানে প্রধান বিপদটি হ'ল আপনি একটি সত্য তবে অ স্ট্রিং মান পাবেন তবে কিছু প্রোগ্রামে এটি কোনও সমস্যা হবে না।
কিন্ডেল করুন

25
এটি অন্যটি ব্যবহার না করলে ডিফল্ট মানটি যদি গুলি না হয় বা মিথ্যা হয় , যা যা চেয়েছিল তা নাও হতে পারে।
পাফকু

6
এটির কারণে অনেকগুলি অস্পষ্ট বাগ রয়েছে। উদাহরণস্বরূপ পাইথন 3.5 এর datetime.time(0)পূর্বেও ছিল মিথ্যা!
আন্তি হাপালা

19
এইটা খারাপ. আমি এর ক্ষতি সম্পর্কে একটি বিজ্ঞপ্তি যুক্ত করার পরামর্শ দিচ্ছি। এবং এটি ব্যবহার না করার পরামর্শ দিচ্ছেন ।
মতিন উলহাক

61

স্ট্রিক্টলি,

other = s if s is not None else "default value"

অন্যথায়, s = Falseহয়ে যাবে "default value", যা উদ্দেশ্য ছিল না হতে পারে।

আপনি যদি এই সংক্ষিপ্ত করতে চান তবে চেষ্টা করুন:

def notNone(s,d):
    if s is None:
        return d
    else:
        return s

other = notNone(s, "default value")

1
Consider x()?.y()?.z()
নুরেটিন

40

এখানে এমন একটি ফাংশন যা প্রথম যুক্তিটি ফিরিয়ে দেবে যা তা নয় None:

def coalesce(*arg):
  return reduce(lambda x, y: x if x is not None else y, arg)

# Prints "banana"
print coalesce(None, "banana", "phone", None)

reduce()প্রথম যুক্তি না থাকলেও অযথা সমস্ত আর্গুমেন্টের উপর পুনরাবৃত্তি হতে পারে None, সুতরাং আপনি এই সংস্করণটিও ব্যবহার করতে পারেন:

def coalesce(*arg):
  for el in arg:
    if el is not None:
      return el
  return None

23
def coalesce(*arg): return next((a for a in arg if a is not None), None)এক লাইনে আপনার শেষ উদাহরণ হিসাবে একই।
glglgl

2
আমি পেয়েছি যে লোকেরা যদি অন্য সিটনাक्स ইত্যাদি ব্যাখ্যা করতে চায় তবে Coalesce একটি স্বেচ্ছাসেবী যুক্তির তালিকা নেয় তাই এটি সত্যই শীর্ষের উত্তর হওয়া উচিত।
এরিক টোলেগার

2
glglgl এর সেরা উত্তর রয়েছে। আমি একটি বড় পরীক্ষার অ্যারে টাইমিট ব্যবহার করেছি এবং হ্রাস বাস্তবায়ন অগ্রহণযোগ্যভাবে ধীর, / যদি সংস্করণটি দ্রুত হয় তবে এর জন্য বহু-লাইন, এবং পরবর্তী বাস্তবায়ন খুব সামান্য পিছনে। সরলতা এবং সংক্ষিপ্ততার বিবেচনা করার পরে পরবর্তী সংস্করণটি সর্বোত্তম সামগ্রিক।
কাদামাটি

3
@glglgl এর আকর্ষণীয় স্নিপেট রয়েছে। দুর্ভাগ্যক্রমে পাইথনের পাস-বাই-নাম নেই, এরকম একত্রিতভাবে শর্ট সার্কিট হয় না; কোড চালানোর আগে সমস্ত আর্গুমেন্ট মূল্যায়ন করা হয়।
ব্যবহারকারী 1338062

Consider x()?.y()?.z()
নুরেটিন

5

আমি বুঝতে পারি যে এটির উত্তর দেওয়া হয়েছে, তবে আপনি যখন অন্য জিনিসগুলির সাথে লেনদেন করছেন তখন অন্য একটি বিকল্প রয়েছে।

আপনার যদি এমন কোনও জিনিস থাকে যা হতে পারে:

{
   name: {
      first: "John",
      last: "Doe"
   }
}

তুমি ব্যবহার করতে পার:

obj.get(property_name, value_if_null)

ভালো লেগেছে:

obj.get("name", {}).get("first", "Name is missing") 

যোগ করে {}ডিফল্ট মান যেমন, যদি "নাম" অনুপস্থিত, একটি খালি বস্তুর ফিরে আসেন এবং পরবর্তী পেতে মাধ্যমে গৃহীত হয়। এটি সি # তে নাল-নিরাপদ নেভিগেশনের অনুরূপ, যা এটির মতো হবে obj?.name?.first


সমস্ত অবজেক্টের নেই .get, এটি কেবল ডিক-এর মতো অবজেক্টের জন্য কাজ করে
22-18 শে

আমি কভার করতে একটি উত্তর সম্পাদনা জমা করছি getattr()
dgw

getডিকটি মান মান না থাকলে ডিফল্ট প্যারামিটার ব্যবহার করে না তবে মানটি উপস্থিত না থাকলে ডিফল্ট প্যারামিটার ব্যবহার করে কারণ কীটি ডিকটিতে নেই। {'a': None}.get('a', 'I do not want None')এখনও Noneফলাফল হিসাবে আপনাকে দিতে হবে ।
প্যাট্রিক মেভিজেক

3

"বা" এর আচরণ সম্পর্কে জুলিয়ানো উত্তর ছাড়াও: এটি "দ্রুত"

>>> 1 or 5/0
1

তাই কখনও কখনও এটি মত জিনিসগুলির জন্য একটি দরকারী শর্টকাট হতে পারে

object = getCachedVersion() or getFromDB()

17
আপনি যে শব্দটির সন্ধান করছেন তা হ'ল "শর্ট সার্কিট"।
jpmc26

1

ফাংশন রিটার্ন মানগুলির অ্যাসেসমেন্ট নাল-চেক করার জন্য, আপনি নতুন ওয়ালরাস-অপারেটরটি ব্যবহার করতে পারেন (পাইথন ৩.৮ থেকে):

def test():
    return

a = 2 if (x:= test()) is None else x

সুতরাং, testফাংশনটি দু'বার মূল্যায়ন করার দরকার নেই (যেমন রয়েছে a = 2 if test() is None else test())


1

আপনার যদি একাধিক নাল কোলেসেসিং অপারেশন বাসা বাঁধতে হয় তবে:

model?.data()?.first()

এটি সহজেই সমাধান করা কোনও সমস্যা নয় or। এটির সাথেও সমাধান করা যায় না .get()যার জন্য অভিধানের ধরণের প্রয়োজন হয় বা অনুরূপ (এবং যেভাবেই getattr()বাসা বাঁধতে পারে না ) বা কোনও ব্যতিক্রম ছুঁড়ে ফেলবে যখন ননটাইপটির বৈশিষ্ট্য নেই।

ভাষায় নাল কোলেসিং যুক্ত করার কথা বিবেচনা করে প্রাসঙ্গিক পাইপটি পিইপি 505 এবং নথির সাথে সম্পর্কিত আলোচনাটি পাইথন- থ্রেড থ্রেডে রয়েছে।


0

@ হুগ বোথওয়েল, @ মরতেহু এবং @glglgl এর উত্তর সম্পর্কে।

পরীক্ষার জন্য ডেটাসেট সেটআপ করুন

import random

dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]

বাস্তবায়ন সংজ্ঞায়িত করুন

def not_none(x, y=None):
    if x is None:
        return y
    return x

def coalesce1(*arg):
  return reduce(lambda x, y: x if x is not None else y, arg)

def coalesce2(*args):
    return next((i for i in args if i is not None), None)

পরীক্ষা ফাংশন করুন

def test_func(dataset, func):
    default = 1
    for i in dataset:
        func(i, default)

পাইথন 2.7 ব্যবহার করে ম্যাক আই 7 @ 2.7Ghz এ ফলাফল z

>>> %timeit test_func(dataset, not_none)
1000 loops, best of 3: 224 µs per loop

>>> %timeit test_func(dataset, coalesce1)
1000 loops, best of 3: 471 µs per loop

>>> %timeit test_func(dataset, coalesce2)
1000 loops, best of 3: 782 µs per loop

পরিষ্কারভাবে not_noneফাংশনটি ওপির প্রশ্নের সঠিক উত্তর দেয় এবং "মিথ্যা" সমস্যাটি পরিচালনা করে। এটি পড়া সবচেয়ে দ্রুত এবং সহজও। যদি অনেক জায়গায় লজিক প্রয়োগ করা হয় তবে এটি পরিষ্কারভাবে যাওয়ার সর্বোত্তম উপায়।

যদি আপনার যদি কোনও সমস্যা হয় যেখানে আপনি পুনরাবৃত্তযোগ্য মধ্যে 1 ম নন-নাল মানটি খুঁজে পেতে চান তবে @ মর্তেহুর প্রতিক্রিয়া হ'ল উপায়। তবে এটি ওপির চেয়ে আলাদা সমস্যার সমাধান , যদিও এটি কেসটি আংশিকভাবে পরিচালনা করতে পারে। এটি পুনরাবৃত্তযোগ্য এবং একটি ডিফল্ট মান নিতে পারে না। শেষ আর্গুমেন্টটি ডিফল্ট মান হিসাবে প্রত্যাবর্তিত হবে, তবে তারপরে আপনি সেই ক্ষেত্রে কোনও পুনরাবৃত্তির সাথে পাশ করবেন না পাশাপাশি এটি স্পষ্ট নয় যে শেষ যুক্তিটি মানের জন্য একটি ডিফল্ট।

তারপরে আপনি নীচে করতে পারেন তবে আমি এখনও not_nullএকক মান ব্যবহারের ক্ষেত্রে ব্যবহার করব।

def coalesce(*args, **kwargs):
    default = kwargs.get('default')
    return next((a for a in arg if a is not None), default)

0

আমার মতো যারা এখানে এই সমস্যাটির একটি কার্যকর সমাধানের সন্ধানে হোঁচট খেয়েছে, যখন ভেরিয়েবলটি অপরিবর্তিত হতে পারে তখন আমার কাছে সবচেয়ে কাছেরটি হ'ল:

if 'variablename' in globals() and ((variablename or False) == True):
  print('variable exists and it\'s true')
else:
  print('variable doesn\'t exist, or it\'s false')

নোট করুন যে গ্লোবালগুলি পরীক্ষা করার সময় একটি স্ট্রিং প্রয়োজন হয়, তবে পরে মানটি পরীক্ষা করার সময় প্রকৃত পরিবর্তনশীল ব্যবহৃত হয়।

চলক অস্তিত্ব সম্পর্কে আরও: ভেরিয়েবলের অস্তিত্ব আছে কিনা তা আমি কীভাবে পরীক্ষা করব?


1
(variablename or False) == Trueহিসাবে একইvariablename == True
মাইক

-2
Python has a get function that its very useful to return a value of an existent key, if the key exist;
if not it will return a default value.

def main():
    names = ['Jack','Maria','Betsy','James','Jack']
    names_repeated = dict()
    default_value = 0

    for find_name in names:
        names_repeated[find_name] = names_repeated.get(find_name, default_value) + 1

যদি আপনি অভিধানের মধ্যে নামটি না খুঁজে পান তবে এটি ডিফল্ট_মূল্যটি ফিরিয়ে দেবে, যদি নামটি বিদ্যমান থাকে তবে এটি 1 সহ যে কোনও বিদ্যমান মান যুক্ত করবে।

আশা করি এটি সাহায্য করতে পারে


1
হাই, স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম আপনার উত্তরটি নতুন কোন তথ্য যুক্ত করে যা ইতিমধ্যে বিদ্যমান উত্তরের দ্বারা আচ্ছাদিত ছিল না? উদাহরণস্বরূপ @ ক্রেগের উত্তর দেখুন
গ্রিসি

-6

অনেক ভেরিয়েবল টেস্টিং কেসগুলির সাথে ডিল করার সময় আমি নীচের দুটি ফাংশনটি খুব দরকারী বলে মনে করেছি।

def nz(value, none_value, strict=True):
    ''' This function is named after an old VBA function. It returns a default
        value if the passed in value is None. If strict is False it will
        treat an empty string as None as well.

        example:
        x = None
        nz(x,"hello")
        --> "hello"
        nz(x,"")
        --> ""
        y = ""   
        nz(y,"hello")
        --> ""
        nz(y,"hello", False)
        --> "hello" '''

    if value is None and strict:
        return_val = none_value
    elif strict and value is not None:
        return_val = value
    elif not strict and not is_not_null(value):
        return_val = none_value
    else:
        return_val = value
    return return_val 

def is_not_null(value):
    ''' test for None and empty string '''
    return value is not None and len(str(value)) > 0

5
এই ধরণের জিনিসগুলি কিছুটা পৃথক পরিভাষা যুক্ত করে (উদাহরণস্বরূপ "নাল" এবং "এনজেড" যার অর্থ পাইথনের প্রসঙ্গে কিছু নয়), অন্যান্য ভাষা থেকে আমদানি করা হয়েছে, এবং এর সাথে বিভিন্ন রূপগুলি (কঠোর বা অ-কঠোর!)। এটি কেবল বিভ্রান্তি যোগ করে। সুস্পষ্ট "কেউ নয়" চেকগুলি আপনার ব্যবহার করা উচিত। এছাড়াও আপনি কোনও ফাংশন কল ব্যবহার করার সময় অপারেটররা যে কোনও সংক্ষিপ্ত-কাটিয়া শব্দার্থবিজ্ঞানের সুবিধা পাবেন না।
spookylukey
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.