কীভাবে একটি তালিকা বোঝার ব্যতিক্রমগুলি পরিচালনা করবেন?


120

পাইথনে আমার কিছু তালিকা উপলব্ধি রয়েছে যাতে প্রতিটি পুনরাবৃত্তি একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে।

উদাহরণস্বরূপ , যদি আমার কাছে থাকে:

eggs = (1,3,0,3,2)

[1/egg for egg in eggs]

আমি ZeroDivisionErrorতৃতীয় উপাদান একটি ব্যতিক্রম পাবেন ।

আমি কীভাবে এই ব্যতিক্রমটি পরিচালনা করতে পারি এবং তালিকার বোধগম্যতা চালিয়ে যেতে পারি?

আমি একমাত্র উপায় হ'ল সহায়ক ফাংশনটি ব্যবহার করা:

def spam(egg):
    try:
        return 1/egg
    except ZeroDivisionError:
        # handle division by zero error
        # leave empty for now
        pass

তবে এটি আমার কাছে কিছুটা জটিল মনে হচ্ছে।

পাইথন এ আরও ভাল উপায় আছে?

দ্রষ্টব্য: এটি একটি সাধারণ উদাহরণ ( উপরে " উদাহরণস্বরূপ " দেখুন) যা আমি স্বীকৃত কারণ আমার আসল উদাহরণটির জন্য কিছু প্রসঙ্গ প্রয়োজন। আমি শূন্য ত্রুটি দ্বারা বিভাজন এড়াতে আগ্রহী নই তবে তালিকার বোধগম্যের ব্যতিক্রমগুলি পরিচালনা করতে।


4
ব্যতিক্রমগুলি পরিচালনা করতে একটি অভিব্যক্তি যোগ করার জন্য একটি পিইপি 463 রয়েছে । আপনার উদাহরণে এটি হবে [1/egg except ZeroDivisionError: None for egg in (1,3,0,3,2)]। তবে এটি এখনও খসড়া মোডে। আমার অন্ত্র অনুভূতি হ'ল এটি গৃহীত হবে না। ইমো এক্সপ্রেশন খুব অগোছালো পেতে পারে (একাধিক ব্যতিক্রমগুলি পরীক্ষা করে, আরও জটিল সংমিশ্রণ (একাধিক লজিকাল অপারেটর, জটিল বোঝা ইত্যাদি) থাকে
সিএফআই

1
দ্রষ্টব্য যে এই নির্দিষ্ট উদাহরণের জন্য, আপনি ndarrayউপযুক্ত সেটিংস সহ একটি নম্পি ব্যবহার করতে পারেন np.seterr। যে ফলাফল হবে 1/0 = nan। তবে আমি বুঝতে পারি যে অন্যান্য পরিস্থিতিতে যেখানে এই প্রয়োজন দেখা দেয় সেখানে সাধারণীকরণ হয় না।
অঙ্কিত

উত্তর:


96

পাইথনে এমন কোনও অন্তর্নির্মিত প্রকাশ নেই যা আপনাকে একটি ব্যতিক্রম উপেক্ষা করতে দেয় (বা ব্যতিক্রমের ক্ষেত্রে বিকল্প মানের & সি ফেরত দিতে পারে), সুতরাং "তালিকার বোঝাপড়াতে ব্যতিক্রমগুলি পরিচালনা করতে" অসম্ভব, আক্ষরিক অর্থে কথা বলা কারণ একটি তালিকা বোধগম্যতা একটি প্রকাশ অন্যান্য অভিব্যক্তি, আরও কিছু নেই (অর্থাত্ কোনও বিবৃতি নেই, এবং কেবলমাত্র বিবৃতিগুলি ব্যতিক্রমগুলি ধরা / উপেক্ষা / পরিচালনা করতে পারে)।

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

"কীভাবে একটি তালিকা বোঝার ব্যতিক্রমগুলি পরিচালনা করতে হবে" এই প্রশ্নের সঠিক প্রতিক্রিয়াগুলি এই সমস্ত সত্যেরই অংশ হিসাবে প্রকাশিত হয়: 1) আক্ষরিক অর্থে, অর্থাত্ সংক্ষেপে নিজেই, আপনি পারবেন না; 2) ব্যবহারিকভাবে, আপনি কোনও ফাংশনে কাজটি অর্পণ করেন বা যখন এটি সম্ভব হয় ত্রুটি প্রবণ মানগুলি পরীক্ষা করে দেখুন। আপনার বারবার দাবি যে এটি কোনও উত্তর নয় তাই ভিত্তিহীন।


14
আমি দেখি. সুতরাং একটি সম্পূর্ণ উত্তর হবে আমার হয়: 1. একটি ফাংশন ব্যবহার করুন 2. তালিকান বোধগম্যতা ব্যবহার করবেন না 3. ব্যতিক্রমটিকে পরিচালনা করার চেয়ে প্রতিরোধ করার চেষ্টা করুন।
নাথান ফেলম্যান

9
আমি "তালিকা বোঝার ক্ষেত্রে কীভাবে ব্যতিক্রমগুলি পরিচালনা করতে পারি" এর উত্তরের অংশ হিসাবে "তালিকার বোধগম্যতা ব্যবহার করছি না" তা দেখতে পাচ্ছি না, তবে আমি অনুমান করি যে আপনি এলসি-তে সংলগ্নভাবে "এর সম্ভাব্য পরিণতি হিসাবে যুক্তিযুক্তভাবে দেখতে পাচ্ছেন , এটি সম্ভব নয় ব্যতিক্রমগুলি পরিচালনা করুন ", যা সত্যই আক্ষরিক উত্তরের প্রথম অংশ part
অ্যালেক্স মার্টেলি

আপনি কি জেনারেটর এক্সপ্রেশন বা জেনারেটর বোঝার ত্রুটি ধরতে পারেন?

1
@ অ্যালেক্সমার্টেল্লি, কোনও ক্লজ বাদ দিয়ে কি ভবিষ্যতের অজগর সংস্করণগুলিতে কাজ করা এত কঠিন? [x[1] for x in list except IndexError pass]। দোভাষী x[1]কী চেষ্টা করার জন্য একটি অস্থায়ী ফাংশন তৈরি করতে পারেন ?
অ্যালাঙ্কলভিটি

@ নাথান, উপরে 1,2,3 ক্রিয়ামূলক তথ্য প্রবাহে প্রচণ্ড মাথাব্যথায় পরিণত হয়েছে যেখানে ১. একজন সাধারণত ল্যাম্বডাসের মাধ্যমে ফাংশনগুলি ইনলাইন করতে চান; ২. বিকল্পটি লুপগুলির জন্য প্রচুর নেস্টেড ব্যবহার করছে যা কার্যকরী দৃষ্টান্ত লঙ্ঘন করে এবং ত্রুটিযুক্ত প্রবণ কোডের দিকে পরিচালিত করে; ৩. প্রায়শই ত্রুটিগুলি হ'ল অ্যাড-হক এবং সুপ্ত জটিল ডেটাসেটগুলি যা ডেটা হিসাবে লাতিন শব্দ হিসাবে বোঝানো হয়, দেওয়া হয়, তাই সহজেই প্রতিরোধ করা যায় না।
আলঙ্কালভিটি

118

আমি বুঝতে পারি এই প্রশ্নটি বেশ পুরানো, তবে আপনি এই জাতীয় জিনিসটি আরও সহজ করতে একটি সাধারণ ফাংশন তৈরি করতে পারেন:

def catch(func, handle=lambda e : e, *args, **kwargs):
    try:
        return func(*args, **kwargs)
    except Exception as e:
        return handle(e)

তারপরে, আপনার উপলব্ধিতে:

eggs = (1,3,0,3,2)
[catch(lambda : 1/egg) for egg in eggs]
[1, 0, ('integer division or modulo by zero'), 0, 0]

আপনি অবশ্যই যা চান ডিফল্ট হ্যান্ডেল ফাংশনটি করতে পারেন (বলুন আপনি ডিফল্টরূপে 'কিছুই না' ফিরিয়ে আনবেন)।

আশা করি এটি আপনাকে বা এই প্রশ্নের ভবিষ্যতের কোনও দর্শকদের সহায়তা করে!

দ্রষ্টব্য: পাইথন 3-তে, আমি কেবল 'হ্যান্ডেল' আর্গুমেন্ট কীওয়ার্ডটি তৈরি করে যুক্তি তালিকার শেষে রেখে দেব। এটি প্রকৃতপক্ষে আর্গুমেন্টগুলি তৈরি করতে পারে এবং এর চেয়ে অনেক বেশি প্রাকৃতিক catch


2
চূড়ান্তভাবে দরকারী, ধন্যবাদ। আমি তাত্ত্বিক মন্তব্যের সাথে একমত হওয়ার পরেও, আমি বারবার যাচ্ছিলাম এমন সমস্যার সমাধান করার জন্য এটি ব্যবহারিক পদ্ধতির দেখায়।
পল

2
গ্রেট উত্তর। একটি মড আমি প্রস্তাব দিচ্ছি যে পাশ দিয়ে চলেছে argsএবং kwargsপাশাপাশি পরিচালনা করতে হবে। এইভাবে আপনি eggহার্ডকডযুক্ত পরিবর্তে বলতে পারেন 0বা আপনি করছেন এমন ব্যতিক্রম।
ম্যাড পদার্থবিদ

3
আপনি ব্যতিক্রমী যুক্তি (ব্যতিক্রম প্রকারগুলি প্যারামিট্রিসড করা যেতে পারে?) হিসাবে ব্যতিক্রম প্রকারটিও চাইতে পারেন, যাতে সমস্ত ব্যতিক্রম উপেক্ষা করার পরিবর্তে অপ্রত্যাশিত ব্যতিক্রমগুলি উপরের দিকে ছুঁড়ে ফেলা হয়।
00 প্রোমিথিউস

3
@ ব্রায়ান, আপনি কি "অজগর 3 তে কোড সরবরাহ করতে পারেন, আমি কেবল 'হ্যান্ডেল' আর্গুমেন্ট কীওয়ার্ডটি তৈরি করে যুক্তি তালিকার শেষে রেখে দেব।" handleপরে রাখার চেষ্টা করে **kwargএকটি পেয়েছি SyntaxError। আপনি হিসাবে dereferences মানে kwargs.get('handle',e)?
আলঙ্কালভিটি

21

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

[1/egg for egg in eggs if egg != 0]

এটি কেবল শূন্যের উপাদানগুলিকে এড়িয়ে যাবে।


28
এটি কোনও তালিকা বোধে ব্যতিক্রমগুলি কীভাবে পরিচালনা করবেন সে প্রশ্নের উত্তর দেয় না।
নাথান ফেলম্যান 21

8
হুম, এটা আছে। এটি ব্যতিক্রমগুলি পরিচালনা করার প্রয়োজনকে বাধা দেয়। হ্যাঁ, এটি সর্বদা সঠিক সমাধান নয়, তবে এটি একটি সাধারণ।
পিটার 21

3
আমি বুঝেছি. আমি মন্তব্যটি প্রত্যাহার করি (যদিও আমি এটি মুছে ফেলব না যেহেতু সেই সংক্ষিপ্ত 'আলোচনার' উত্তরে উন্নতি হয়েছে)।
নাথান ফেলম্যান

11

না এর চেয়ে ভাল উপায় আর নেই। অনেক ক্ষেত্রে আপনি পিটারের মতো এড়ানো ব্যবহার করতে পারেন

আপনার অন্য বিকল্পটি বোধগম্যতা না ব্যবহার করা

eggs = (1,3,0,3,2)

result=[]
for egg in eggs:
    try:
        result.append(egg/0)
    except ZeroDivisionError:
        # handle division by zero error
        # leave empty for now
        pass

আপনারা সিদ্ধান্ত নিতে পারেন যে এটি আরও জটিল বা না


1
আমি কিভাবে এখানে বোঝাপড়া ব্যবহার করব?
নাথান ফেলম্যান 21

@ নাথান: আপনি না। gnibbler বলেছেন: না এর চেয়ে ভাল উপায় আর নেই
সাইলেন্টগোস্ট

দুঃখিত ... আমি তার উত্তরে '
নট

4

আমি মনে করি একটি সহায়ক ফাংশন, যিনি প্রাথমিক প্রশ্ন জিজ্ঞাসা করেছেন এবং ব্রায়ান হেডের পরামর্শ হিসাবে বলা হয়েছে, এটি ভাল এবং মোটেও জটিল নয়। সমস্ত কাজ করে এমন ম্যাজিক কোডের একক লাইন কেবল সর্বদা সম্ভব নয় তাই কোনও forলুপগুলি এড়াতে চাইলে কোনও সহায়ক ফাংশন একটি নিখুঁত সমাধান । তবে আমি এটি এটিকে সংশোধন করব:

# A modified version of the helper function by the Question starter 
def spam(egg):
    try:
        return 1/egg, None
    except ZeroDivisionError as err:
        # handle division by zero error        
        return None, err

আউটপুট এটি হবে [(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]। এই উত্তরের সাথে আপনি যেভাবে চান চালিয়ে যেতে সম্পূর্ণ নিয়ন্ত্রণে আছেন।


খুশী হলাম। এটি Eitherকিছু ফাংশনাল প্রোগ্রামিং ল্যাঙ্গুয়েজের (যেমন স্কালার) মতো ধরণের সাথে খুব মিল দেখায় যেখানে Eitherএকটিতে এক ধরণের বা অন্য একটির মান থাকতে পারে তবে উভয়ই নয়। পার্থক্যটি হ'ল এই ভাষাগুলিতে ত্রুটিটি বাম দিকে এবং ডান দিকে মানটি রাখা মুশকিল। এখানে আরও তথ্য সহ একটি নিবন্ধ দেওয়া আছে
অ্যালেক্স পামার

3

আমি কোন উত্তর এই উল্লেখ করতে দেখিনি। তবে এই উদাহরণটি হ'ল পরিচিত ব্যর্থতার ক্ষেত্রে ব্যতিক্রম উত্থাপন থেকে রোধ করার এক উপায়।

eggs = (1,3,0,3,2)
[1/egg if egg > 0 else None for egg in eggs]


Output: [1, 0, None, 0, 0]

এই উত্তর হিসাবে একই হয় না? stackoverflow.com/a/1528244/1084
নাথান ফেলম্যান

একটি সূক্ষ্ম পার্থক্য আছে। ফিল্টারিং ইনপুট তালিকার চেয়ে আউটপুটটিতে প্রয়োগ করা হয়। আপনি পোস্টের উদাহরণে দেখতে পাচ্ছেন, যে মামলাটির ব্যতিক্রম হতে পারে তার জন্য আমি "কিছুই নয়" চিহ্নিত করেছি।
স্লেকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.