কীভাবে একাধিক লুপ ভেঙে যায়?


478

নিম্নলিখিত কোড দেওয়া (এটি কাজ করে না):

while True:
    #snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok.lower() == "y": break 2 #this doesn't work :(
        if ok.lower() == "n": break
    #do more processing with menus and stuff

এই কাজ করার কোন উপায় আছে? অথবা ইনপুট লুপটি ভেঙে ফেলার জন্য আমার কাছে কি একটি চেক আছে, তারপরে আরেকটি, আরও সীমাবদ্ধ, যদি صارف সন্তুষ্ট হয় তবে বাইরের লুপটি সমস্ত একসাথে বিভক্ত করার জন্য চেক করুন?


87
পাইথনের কেন কেবল 'ব্রেক (n)' নেই কেন যেখানে এন আপনি যে স্তরগুলি ছিন্ন করতে চান তার সংখ্যা।
নাথান

2
সি ++ এখানে খুব সুন্দর gotoযদি আপনি অনেকগুলি লুপগুলিতে গভীরভাবে বেঁধে থাকেন
ড্রেক জনসন

উত্তর:


511

আমার প্রথম প্রবৃত্তিটি কোনও ফাংশনে নেস্টেড লুপটি রিফ্যাক্টর করা এবং returnব্রেক আউট ব্যবহার করা হবে।


3
এটি আমার আরেকটি ধারণা ছিল, যেহেতু get_input_yn () ফাংশন অন্য কোথাও কার্যকর হবে, আমি নিশ্চিত।
ম্যাথু শার্লে

96
এই সুনির্দিষ্ট ক্ষেত্রে সম্মত, তবে 'আমি লম্পট লুপ করেছি, আমি কি করব' এর সাধারণ ক্ষেত্রে রিফ্যাক্টরিংটি বোধগম্য নয়।
quick_dry

আপনি যদি রিটার্ন ব্যবহারের পরিবর্তে ফলন করতে পারেন তবে একটি ব্যতিক্রম ব্যবহার করা সহজ হতে পারে তবে আপনার সম্ভবত এটির ক্ষেত্রে itertools.islice () ব্যবহার করা উচিত।
রবার্ট কিং

5
অভ্যন্তরীণ লুপটিকে তার নিজস্ব পদ্ধতিতে রিফ্যাক্টর করা সাধারণত সম্ভব হয়, যা চালিয়ে যেতে সত্য হয় এবং বাহ্যিক লুপটি ভাঙতে মিথ্যা হয়। শর্ত 1: / না হলে MyLoop2 (প্যারাম): বিরতি। বিকল্পটি হ'ল বুলিয়ান পতাকা সেট করা, এটি উভয় স্তরে পরীক্ষা করা হয়। আরও = সত্য / যখন শর্ত 1 এবং আরও: / যখন শর্ত 2 এবং আরও: / if স্টপ কন্ডিশন: আরও = মিথ্যা / বিরতি / ...
টুলমেকারস্টেভ

7
আমি সম্মত যে ব্যবহার করার চেষ্টা করা returnসঠিক পদ্ধতির is এবং যুক্তিটি হ'ল পাইথনের জেন অনুসারে "ফ্ল্যাটটি নেস্টেডের চেয়ে ভাল better" আমাদের এখানে তিনটি স্তরের বাসা বাঁধে এবং যদি এটি পথে আসতে শুরু করে তবে নীড় বাড়াতে হ্রাস করার বা কমপক্ষে পুরো বাসাটি তার নিজস্ব কোনও ক্রিয়ায় সরিয়ে নেওয়ার সময়।
লুটজ প্রিচেল্ট

239

এখানে অন্য পদ্ধতির সংক্ষিপ্ত। অসুবিধাটি হ'ল আপনি কেবল বাইরের লুপটি ভেঙে ফেলতে পারেন তবে কখনও কখনও এটি আপনি যা চান ঠিক তেমন হয়।

for a in xrange(10):
    for b in xrange(20):
        if something(a, b):
            # Break the inner loop...
            break
    else:
        # Continue if the inner loop wasn't broken.
        continue
    # Inner loop was broken, break the outer.
    break

এটি এখানে বর্ণিত / অন্য নির্মাণের জন্য ব্যবহার করে: অজগর লুপগুলির পরে এবং কেন 'অন্য' ব্যবহার করে?

মূল অন্তর্দৃষ্টি: মনে হয় কেবল বাহিরের লুপটি সর্বদা বিরতিতে থাকে। তবে যদি ভিতরের লুপটি না ভাঙে তবে বাইরের লুপটি আর হয় না।

continueবিবৃতি জাদু এখানে। এটি অন্য কোনও দফায় রয়েছে। সংজ্ঞা অনুসারে এটি ঘটে যদি কোনও অভ্যন্তরীণ বিরতি না থাকে। এই পরিস্থিতিতে খুব continueসুন্দরভাবে বাইরের বিরতি পরিলক্ষিত হয়।


6
@ ইউজনি কেন নয়? প্রথম বিরতিটি ভিতরের লুপ থেকে বেরিয়ে আসবে।
নবীন

5
@ ইউজনি আমার মনে হচ্ছে আমি এখানে কিছু মিস করছি। আপনি একটি উদাহরণ পোস্ট করতে পারেন?
নবীন

4
চালিয়ে যাওয়ার আগে যেতে পারেন @ মিংগ্লিয়ং
বাল্ড্রিক

1
এটি একটি রেমন্ড হেটিঙ্গার ভিডিও থেকে পেয়েছেন, youtu.be/OSGv2VnC0go?t=971 , "no_break" হিসাবে লুপগুলির সাথে যুক্ত "অন্য" বিবৃতি পড়ুন, তারপরে এটি বোঝা সহজ হয়ে যায়।
আম্বারেশ

2
এই চালাক। :-) তবে, সরাসরি-এগিয়ে নয়। সত্যই, লেবেল বিরতি বা ব্রেক (এন) পাইথন থেকে দূরে রাখতে আমি যুক্তি দ্বারা নিশ্চিত নই by কাজের ক্ষেত্রগুলি আরও জটিলতা যুক্ত করে।
rfportilla

148

পিইপি 3136 লেবেল বিরতি / চালিয়ে যাওয়ার প্রস্তাব দেয়। গিডো এটিকে প্রত্যাখ্যান করেছে কারণ "এই বৈশিষ্ট্যটির প্রয়োজনের জন্য কোড এত জটিল" খুব বিরল "। পিইপি কিছু কাজের ক্ষেত্র উল্লেখ করেছে, যদিও (যেমন ব্যতিক্রম কৌশল), অন্যদিকে গিডো মনে করেন যে রিটার্ন ব্যবহারের জন্য রিফ্যাক্টরিং বেশিরভাগ ক্ষেত্রেই সহজ হবে।


73
যদিও, রিফ্যাক্টর / returnসাধারণত যাবার উপায়, আমি বেশ কয়েকটি কেস দেখেছি যেখানে একটি সাধারণ সংক্ষিপ্ত break 2বিবৃতি কেবল এতটা বোঝায়। এছাড়াও, রিফ্যাক্টর / এর returnজন্য একই কাজ করে না continue। এই ক্ষেত্রে, সংখ্যা বিরতি এবং চালিয়ে যাওয়া ছোট্ট ফাংশনটিতে রিফ্যাক্টর করা, ব্যতিক্রমগুলি উত্থাপন বা প্রতিটি নীড় স্তরে পতাকা ভাঙার জন্য জড়িত যুক্তিযুক্ত যুক্তির চেয়ে অনুসরণ করা সহজ এবং কম বিশৃঙ্খলা। এটি লজ্জাজনক বিষয় যা গিডো এটিকে প্রত্যাখ্যান করেছিল।
জেমস হাই 18

10
break; breakসুন্দর হবে.
পাইরুলেজ

5
@ জিয়েকোমন সমস্যা হ'ল সমস্যা হওয়ার জন্য আপনার 3 বা আরও বেশি নেস্টেড লুপের দরকার নেই। 2 নেস্টেড লুপগুলি বেশ সাধারণ
জন

6
"এই বৈশিষ্ট্যটির প্রয়োজন এত জটিল কোড খুব বিরল"। তবে আপনি যদি কখনও কোডটি জটিল ব্যবহার করেন তবে লেবেলযুক্ত লুপের অভাব এটিকে আরও জটিল করে তুলবে, কারণ আপনাকে অবশ্যই breakসমস্ত লুপের মাধ্যমে ম্যানুয়ালি ফরোয়ার্ড করতে হবে । মূঢ়।
বলপয়েন্টবেন

3
স্পষ্টতই, আমি কেবল 5 মিনিটের জন্য একটি পোস্ট সম্পাদনা করতে পারি (এটি 6 বছর হয়েছে)। সুতরাং, আমার সম্পাদিত পোস্টটি এখানে: আমার 2 সেন্ট: পার্ল সরাসরি ব্রেকটির লেবেলযুক্ত করেছে (তবে এটিকে 'শেষ' বলে ডাকে) এবং সরাসরি পরবর্তী পুনরাবৃত্তিতে এগিয়ে যেতে 'পরের' বলে। এটি মোটেও বিরল নয় - আমি এটি সর্বদা ব্যবহার করি। আমি পাইথনে একেবারে নতুন এবং এর জন্য ইতিমধ্যে একটি প্রয়োজনীয়তা রয়েছে। এছাড়াও, সংখ্যাযুক্ত বিরতিগুলি রিফ্যাক্টরিংয়ের জন্য ভয়াবহ হতে পারে - আপনি যে লুপটি ভেঙে ফেলতে চান তা লেবেল করা ভাল, তবে আপনি কোন লুপটি ভেঙে ফেলতে চান তা স্পষ্টভাবে জানাতে বিরতি <লেবেল> ব্যবহার করুন।
জন দেইঘান

119

প্রথমত, সাধারণ যুক্তি সহায়ক।

যদি, কোনও কারণে, সমাপ্তির শর্তগুলি কার্যকর করা যায় না, ব্যতিক্রমগুলি হ'ল পতনের পরিকল্পনা।

class GetOutOfLoop( Exception ):
    pass

try:
    done= False
    while not done:
        isok= False
        while not (done or isok):
            ok = get_input("Is this ok? (y/n)")
            if ok in ("y", "Y") or ok in ("n", "N") : 
                done= True # probably better
                raise GetOutOfLoop
        # other stuff
except GetOutOfLoop:
    pass

এই নির্দিষ্ট উদাহরণের জন্য, একটি ব্যতিক্রম প্রয়োজন হতে পারে না।

অন্যদিকে, অক্ষর-মোড অ্যাপ্লিকেশনগুলিতে আমাদের প্রায়শই "ওয়াই", "এন" এবং "কিউ" বিকল্প থাকে। "কিউ" বিকল্পের জন্য আমরা তাত্ক্ষণিক প্রস্থান চাই। এটি আরও ব্যতিক্রমী।


4
গুরুতরভাবে, ব্যতিক্রমগুলি অত্যন্ত সস্তা এবং আইডোমেটিক পাইথনগুলি প্রচুর এবং তাদের প্রচুর ব্যবহার করে। এটি কাস্টমগুলি সংজ্ঞায়িত করা এবং নিক্ষেপ করা খুব সহজ।
গ্রেগ লিন্ড

13
আকর্ষণীয় ধারণা। আমি এটিকে ভালবাসি বা ঘৃণা করি কিনা সে সম্পর্কে আমি ছিন্ন ছিটে।
ক্রেগ ম্যাককুইন

8
এই সমাধানটি আরও সহায়ক হবে, যদি এটি দুটি পৃথকভাবে দেখায়। (1) একটি পতাকা ব্যবহার করে ( done)। (2) একটি ব্যতিক্রম উত্থাপন। এগুলিকে একক সমাধানে একত্রিত করা এটিকে জটিল দেখায়। ভবিষ্যতের পাঠকদের জন্য: এতে জড়িত সমস্ত লাইন ব্যবহার করুন done, বা GetOutOfLoop(Exception)ব্যতীত সংজ্ঞায়িত এবং উত্থাপন করুন।
টুলমেকারস্টেভ

4
সাধারণভাবে, অন্য যে কোনও কিছুর জন্য ট্র্যাক-ব্লক ব্যবহার করা ব্যতিক্রমগুলি খুব ভ্রূণ্য হয়। ট্রায়-ব্লকগুলি বিশেষত ত্রুটি পরিচালনার জন্য ডিজাইন করা হয়েছে এবং স্টাইলিস্টিকভাবে কিছু অদ্ভুত নিয়ন্ত্রণ প্রবাহের জন্য এগুলি ব্যবহার করা খুব ভাল নয়।
নোবিলিগ্রিন

2
পাইথন 3 এ এটি হবে raise Exception('GetOutOfLoop')এবং except Exception:
tommy.carstensen

54

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

from contextlib import contextmanager
@contextmanager
def nested_break():
    class NestedBreakException(Exception):
        pass
    try:
        yield NestedBreakException
    except NestedBreakException:
        pass

এখন আপনি নিম্নলিখিত হিসাবে এই প্রসঙ্গে পরিচালক ব্যবহার করতে পারেন:

with nested_break() as mylabel:
    while True:
        print "current state"
        while True:
            ok = raw_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": raise mylabel
            if ok == "n" or ok == "N": break
        print "more processing"

সুবিধাগুলি: (1) এটি সামান্য ক্লিনার (কোনও ব্লক ব্যতীত স্পষ্ট করে দেখার চেষ্টা নেই) এবং (২) আপনি Exceptionপ্রতিটি ব্যবহারের জন্য একটি কাস্টম বিল্ট সাবক্লাস পাবেন nested_break; আপনার নিজের Exceptionসাবক্লাসটি প্রতিবার ঘোষণা করার দরকার নেই ।


40

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

এছাড়াও আপনি ব্যবহার করতে পারেন এতে যান নিম্নলিখিত পদ্ধতিতে (থেকে একটি এপ্রিল ফুল মডিউল ব্যবহার করে এখানে ):

#import the stuff
from goto import goto, label

while True:
    #snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": goto .breakall
        if ok == "n" or ok == "N": break
    #do more processing with menus and stuff
label .breakall

আমি জানি, আমি জানি, "তুমি গোটো ব্যবহার করবে না" এবং এগুলি সমস্ত কিছুই নয়, তবে এটি এইরকম অদ্ভুত ক্ষেত্রে ভাল কাজ করে।


1
এটি যদি ইন্টারকলের COME FROM কমান্ডের মতো কিছু হয় তবে কিছুই নেই
1800 তথ্য

3
আমি রসিকতাটি পছন্দ করি তবে স্ট্যাকের ওভারফ্লোর বিষয়টি হ'ল ভাল কোড প্রচার করা, সুতরাং আপনাকে আমি ভোট দিতে হবে :(
ক্রিশ্চিয়ান ওডার্ড

13
আমি মনে করি এটি ভাল কোড হিসাবে যোগ্যতা অর্জনের জন্য একটি পরিষ্কার এবং পঠনযোগ্য যথেষ্ট সমাধান, তাই আমি এটিকে ভোট দিয়েছি। :)
জেটি হারলি

1
@ JTHurley না এটি পরিষ্কার এবং পাঠযোগ্য নয়। আমি বোঝাতে চাইছি, এই উদাহরণটিতে এটি পরিষ্কার এবং পাঠযোগ্য বলে মনে হতে পারে তবে কোনও বাস্তব জীবনের দৃশ্যে গোটো একটি পবিত্র জগাখিচুড়ি তৈরি করে । (এছাড়াও এটি স্যুও অ্যান্টি-
পাইথোনিক

2
গোটো খারাপ প্রতিক্রিয়া পেয়েছে, কোনও পেশাদার কোডার আমার মতে এটি সঠিকভাবে পরিচালনা করতে সক্ষম হবে।
অ্যালবার্ট রেনশওয়া

33

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

breaker = False #our mighty loop exiter!
while True:
    while True:
        if conditionMet:
            #insert code here...
            breaker = True 
            break
    if breaker: # the interesting part!
        break   # <--- !

আপনার যদি অসীম লুপ থাকে তবে এটাই একমাত্র উপায়; অন্যান্য লুপের জন্য কার্যকর করা খুব দ্রুত a আপনার অনেক নেস্ট লুপ থাকলে এটিও কাজ করে। আপনি সমস্ত, বা মাত্র কয়েকজন প্রস্থান করতে পারেন। অপার সম্ভাবনার! আশা করি এটি সাহায্য করেছে!


22

কোনও ফাংশনে রিফ্যাক্টর না করে একাধিক নেস্টেড লুপগুলি ভেঙে ফেলার জন্য অন্তর্নির্মিত স্টপআইটিরেশন ব্যতিক্রম সহ "সিমুলেটেড গোটো স্টেটমেন্ট" ব্যবহার করুন :

try:
    for outer in range(100):
        for inner in range(100):
            if break_early():
                raise StopIteration

except StopIteration: pass

নেস্টেড লুপগুলি ভেঙে ফেলার জন্য গোটো স্টেটমেন্টের ব্যবহার সম্পর্কে এই আলোচনাটি দেখুন ।


1
ব্যতিক্রমটি পরিচালনা করার জন্য এটি আপনার নিজের ক্লাস তৈরির চেয়ে আরও সুন্দর দেখাচ্ছে এবং খুব পরিষ্কার দেখাচ্ছে। আমার এমনটি করা উচিত নয় এমন কোনও কারণ আছে?
মিগজেক

প্রকৃতপক্ষে স্টপ ইন্টেরেশন জেনারেটরগুলির জন্য ব্যবহার করছে, তবে আমি মনে করি সাধারণত আপনার কোনও স্ট্যাচইটারেশন ব্যতিক্রম নেই। সুতরাং এটি একটি ভাল সমাধান বলে মনে হচ্ছে তবে যাইহোক নতুন ব্যতিক্রম তৈরি করার ক্ষেত্রে কোনও ভুল নেই।
কোওলস্কি

1
আমার জন্য সেরা এবং সহজ সমাধান
আলেকজান্দ্রে হুয়াট

16

keeplooping=True
while keeplooping:
    #Do Stuff
    while keeplooping:
          #do some other stuff
          if finisheddoingstuff(): keeplooping=False

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


এই ধরণের পতাকা সেটিং!
এসআইসলাম

আমি এটি একটি খুব ভাল সমাধান বলে মনে করি।
কোওলস্কি

13

এটি এটি করার সর্বোত্তম উপায় নয়, তবে আমার মতে এটি সর্বোত্তম উপায়।

def loop():
    while True:
    #snip: print out current state
        while True:
            ok = get_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": return
            if ok == "n" or ok == "N": break
        #do more processing with menus and stuff

আমি নিশ্চিত যে আপনি এখানেও পুনরাবৃত্তি ব্যবহার করে কিছু কাজ করতে পেরেছিলেন তবে আমি যদি জানি না তবে এটি আপনার পক্ষে ভাল বিকল্প un


এটি আমার জন্য সঠিক সমাধান ছিল। আমার ব্যবহারের ক্ষেত্রে ওপি'র তুলনায় খুব আলাদা ছিল। আদেশের সন্ধানের জন্য আমি একই ডেটা দু'বার লুপ করছি, তাই লুপের সময় আমি দুটি আলাদা করতে চাইনি।
ব্রায়ান পিটারসন

9

এবং দুটি শর্ত সত্য হলে লুপিং রাখবেন না কেন? আমি মনে করি এটি একটি আরও অজগর উপায়:

dejaVu = True

while dejaVu:
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y" or ok == "n" or ok == "N":
            dejaVu = False
            break

তাই না?

শুভকামনা.


শুধু না কেন while dejaVu:? আপনি যেভাবেই হোক না কেন এটি সত্য করে দিয়েছেন।
ম্যাথু শার্লে

আরে যে কাজ করে! আমি Trueদুটি লুপ এড়িয়ে যাওয়ার জন্য দুটি অবস্থাতেই ভাবছিলাম , তবে কেবল একটি যথেষ্ট।
মাউরো অ্যাস্পি

2
@ ম্যাথেজশার্লি আমার মনে হয় এটি নীড়যুক্ত লুপগুলিতে কাজ করে তা দেখানো।
হ্যান্ডেল করুন

@ মাউরোএস্প é এটি ওপি অনুরোধের অনুরূপভাবে করবে না। এটি এখনও পুরো বাহ্যিক লুপটি কার্যকর করবে তবে লক্ষ্য হ'ল আপনি যদি বাকী কোডটি ভাঙেন তবে সম্পাদিত হবে না
yamm

@ আইয়ামএম কি if not dejaVu: breakএটি নীচে একটি দিয়ে সমাধান করা যাবে না এবং এভাবে মূল লুপটি থেকে বেরিয়ে আসবে? আমি মনে করি সমাধানটি যা জিজ্ঞাসা করা হয়েছিল তার নিকটতম। +1
মিল্কাক

8

আপনার লুপ যুক্তিটিকে একটি পুনরুক্তি হিসাবে ফ্যাক্টর করুন যা লুপ ভেরিয়েবলগুলি দেয় এবং সম্পন্ন হলে ফিরে আসে - এখানে একটি সরল চিত্র রয়েছে যা সারি / কলামগুলিতে চিত্রগুলি রাখে যতক্ষণ না আমরা চিত্রের বাইরে থাকি বা স্থানগুলি বাইরে রাখি না:

def it(rows, cols, images):
    i = 0
    for r in xrange(rows):
        for c in xrange(cols):
            if i >= len(images):
                return
            yield r, c, images[i]
            i += 1 

for r, c, image in it(rows=4, cols=4, images=['a.jpg', 'b.jpg', 'c.jpg']):
    ... do something with r, c, image ...

জটিল লুপ লজিক এবং প্রক্রিয়াজাতকরণ বিভক্ত করার এর সুবিধা রয়েছে ...


3

এই ক্ষেত্রে, অন্যদের দ্বারাও নির্দেশিত হিসাবে, কার্যকরী পচা হবার উপায়। পাইথন 3 তে কোড:

def user_confirms():
    while True:
        answer = input("Is this OK? (y/n) ").strip().lower()
        if answer in "yn":
            return answer == "y"

def main():
    while True:
        # do stuff
        if user_confirms():
            break

3

পাইথন while ... elseকাঠামোর একটি গোপন কৌশল রয়েছে যা অনেক কোড পরিবর্তন / সংযোজন ছাড়াই ডাবল ব্রেক অনুকরণ করতে ব্যবহার করা যেতে পারে। মূলত whileশর্তটি মিথ্যা হলে, elseব্লকটি ট্রিগার করা হয়। কোনও ব্যতিক্রম নয় continueবা ব্লকটি breakট্রিগার করবে না else। আরও তথ্যের জন্য " বিবৃতি দেওয়ার সময় পাইথন সম্পর্কিত অন্য ধারা ", বা পাইথন ডকটির উত্তর দেখুন (v2.7)

while True:
    #snip: print out current state
    ok = ""
    while ok != "y" and ok != "n":
        ok = get_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N":
            break    # Breaks out of inner loop, skipping else

    else:
        break        # Breaks out of outer loop

    #do more processing with menus and stuff

একমাত্র খারাপ দিকটি হ'ল আপনাকে ডাবল ব্রেকিং শর্তটিকে অবস্থার মধ্যে স্থানান্তর করতে হবে while(অথবা একটি পতাকা পরিবর্তনশীল যুক্ত করতে হবে)। এর বিভিন্নতা forলুপের জন্যও বিদ্যমান , যেখানে elseলুপ শেষ হওয়ার পরে ব্লকটি ট্রিগার করা হয়।


এটি ডাবল ব্রেকের প্রয়োজনীয়তা পূরণ করবে বলে মনে হয় না। যথাযথ প্রদত্ত সমস্যার জন্য কাজ করে তবে প্রকৃত প্রশ্নের জন্য নয়।
ডাকারন

@ ডাকারন আপনি কি নিশ্চিত কোডটি সঠিকভাবে বুঝতে পেরেছেন? কোডটি সত্যই ওপিএসের প্রশ্নটি সমাধান করে এবং অনুরোধের মতো বিরতি দেয়। এটি একাধিক লুপগুলি ভেঙে যায় না, তবে ব্রেকটি দ্বিগুণ করার প্রয়োজনীয়তার প্রতিস্থাপনের জন্য অন্য ধারাটি ব্যবহার করে।
হলি

আমার বোধ থেকে প্রশ্নটি ছিল How to break out of multiple loops in Python?এবং উত্তরটি হওয়া উচিত "এটি কাজ করে না, অন্য কিছু চেষ্টা করুন"। আমি জানি এটি ওপির সঠিক প্রদত্ত উদাহরণটি ঠিক করে, তবে তাদের প্রশ্নের উত্তর দেয় না।
ডাকারন

@ ডাকারন, কোডের নীচে সমস্যার বিবৃতি দেখুন এবং আমার মতে এটি সত্যই ওপিএস প্রশ্নের উত্তর দেয়।
holroy

2

আপনার পুনরাবৃত্তিকে একটি একক-স্তরের লুপে হ্রাস করার অন্য উপায়টি জেনারেটরের ব্যবহারের মাধ্যমে পাইথন রেফারেন্সে উল্লিখিত হবে

for i, j in ((i, j) for i in A for j in B):
    print(i , j)
    if (some_condition):
        break

আপনি এটিকে লুপের জন্য কোনও স্তরের পরিমাণ পর্যন্ত স্কেল করতে পারেন

খারাপ দিকটি হ'ল আপনি আর কেবল একটি মাত্র স্তর ভাঙ্গতে পারবেন না। এটা সব কিছুই না।

আরেকটি নেতিবাচক দিকটি এটি লুপের সাথে কাজ করে না। আমি মূলত পাইথনে এই উত্তরটি পোস্ট করতে চেয়েছিলাম - সমস্ত লুপের বাইরে `ব্রেক` তবে দুর্ভাগ্যক্রমে এটি এইটির সদৃশ হিসাবে বন্ধ হয়ে গেছে


1
এটি লুপগুলি খুব বেশি সময় ধরে কাজ করে, আপনার জেনারেটরটি কেবল একটি ডিফ হিসাবে (ফলন সহ) লিখতে হবে, বোঝার জন্য নয়।
ভিকি

হ্যাঁ, পাইকনের একজন স্পিকার এখানে দাবি করেছেন যে এমনকি @ রবার্টরোসনির গৃহীত উত্তরও সত্যই পাইথোনিক নয়, তবে একাধিক লুপ ভাঙার সঠিক উপায় হ'ল জেনারেটর। (আমি পুরো ভিডিওটি দেখার পরামর্শ দিই!)
0169

2

আমার এখানে আসার কারণ হ'ল আমার একটি বাহ্যিক লুপ এবং এর মতো একটি অভ্যন্তরীণ লুপ ছিল:

for x in array:
  for y in dont_use_these_values:
    if x.value==y:
      array.remove(x)  # fixed, was array.pop(x) in my original answer
      continue

  do some other stuff with x

আপনি দেখতে পাচ্ছেন, এটি আসলে পরবর্তী x এ যাবে না, তবে এর পরিবর্তে পরবর্তী y এ যাবে।

আমি যা সমাধান করতে পেরেছিলাম তা হ'ল পরিবর্তে দু'বার অ্যারে দিয়ে চালানো:

for x in array:
  for y in dont_use_these_values:
    if x.value==y:
      array.remove(x)  # fixed, was array.pop(x) in my original answer
      continue

for x in array:
  do some other stuff with x

আমি জানি এটি ওপি-র প্রশ্নের একটি নির্দিষ্ট কেস ছিল, তবে আমি এটিকে এই পোস্টে পোস্ট করছি যে বিষয়টিকে সহজ রাখার সময় কারও সমস্যা সম্পর্কে আলাদাভাবে ভাবতে সহায়তা করবে।


এটি সম্ভবত পাইথন নয়। অ্যারের ধরণ কী? সম্ভবত তালিকাবদ্ধ করুন, তবে এতে কী রয়েছে? এমনকি এতে অন্তর্নিহিত রয়েছে, অ্যারে.পপ (এক্স) সম্ভবত আপনি যা চান তা করতে পারে না।
ভিকি

এটা একটা ভাল দিক. আমি যে কোডটি উল্লেখ করেছি সেটি খুঁজে পাচ্ছি না। যে কারও এটি পড়ার জন্য, অ্যারে.পপ (i) "আমি অ্যারে থেকে সূচকটি দিয়ে আইটেমটি সরিয়ে ফেরত দিয়েছি।" পাইথন ডকুমেন্টেশন অনুযায়ী। সুতরাং এই কোডটি প্রত্যাশা অনুযায়ী কাজ করতে অ্যারেতে আইটেম এক্সের সূচক পাওয়া দরকার। এছাড়াও অ্যারে রয়েছে.রেমোভ (এক্স) ফাংশন যা প্রত্যাশিতভাবে কাজ করবে। আমি ত্রুটিটি ঠিক করতে উপরে আমার উত্তরটি সংশোধন করব। এটি ধরে নিয়েছে যে দ্বিতীয় অ্যারেতে কোনও সদৃশ নেই, কারণ অ্যারে.রেমোভ (এক্স) কেবলমাত্র পাওয়া x এর প্রথম উদাহরণটি সরিয়ে ফেলবে।
নাথান গারাবেদিয়ান

ঠিক আছে, তাহলে আমি এটি পেয়েছি। সেক্ষেত্রে কেবল breakপরিবর্তে ব্যবহার করা যা continueচাইলে তা করবে, তাই না? :-)
ভিকি

হ্যাঁ, দক্ষতা এবং স্পষ্টতার জন্য আপনি সম্ভবত এই উদাহরণগুলিতে চালিয়ে যাওয়ার পরিবর্তে বিরতি ব্যবহার করতে চান। :)
নাথান গারাবেদিয়ান

2

অসীম জেনারেটর ব্যবহার করে দেখুন।

from itertools import repeat
inputs = (get_input("Is this ok? (y/n)") for _ in repeat(None))
response = (i.lower()=="y" for i in inputs if i.lower() in ("y", "n"))

while True:
    #snip: print out current state
    if next(response):
        break
    #do more processing with menus and stuff

2

একটি ফাংশন ব্যবহার করে:

def myloop():
    for i in range(1,6,1):  # 1st loop
        print('i:',i)
        for j in range(1,11,2):  # 2nd loop
            print('   i, j:' ,i, j)
            for k in range(1,21,4):  # 3rd loop
                print('      i,j,k:', i,j,k)
                if i%3==0 and j%3==0 and k%3==0:
                    return  # getting out of all loops

myloop()

উপরের কোডগুলিতে মন্তব্য করে চালানোর চেষ্টা করুন return পাশাপাশি ।

কোনও ফাংশন ব্যবহার না করে:

done = False
for i in range(1,6,1):  # 1st loop
    print('i:', i)
    for j in range(1,11,2):  # 2nd loop
        print('   i, j:' ,i, j)
        for k in range(1,21,4):  # 3rd loop
            print('      i,j,k:', i,j,k)
            if i%3==0 and j%3==0 and k%3==0:
                done = True
                break  # breaking from 3rd loop
        if done: break # breaking from 2nd loop
    if done: break     # breaking from 1st loop

এখন, উপরের কোডগুলি প্রথম মতো চালান এবং তারপরে breakনীচে থেকে প্রতিটি লাইনে একটি করে মন্তব্য করে চালানোর চেষ্টা করুন ।


2

একাধিক লুপকে একক, ব্রেকযোগ্য লুপে পরিণত করার একটি সহজ উপায় ব্যবহার করা use numpy.ndindex

for i in range(n):
  for j in range(n):
    val = x[i, j]
    break # still inside the outer loop!

for i, j in np.ndindex(n, n):
  val = x[i, j]
  break # you left the only loop there was!

স্পষ্টভাবে মানগুলির মধ্যে পুনরাবৃত্তি করতে সক্ষম হওয়ার বিপরীতে আপনাকে আপনার অবজেক্টগুলিতে সূচি দিতে হবে, তবে কমপক্ষে সহজ ক্ষেত্রে এটি বেশিরভাগ প্রস্তাবিত উত্তরগুলির চেয়ে প্রায় 2-20 গুণ সহজ বলে মনে হয়।


2
# this version uses a level counter to choose how far to break out

break_levels = 0
while True:
    # snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y":
            break_levels = 1        # how far nested, excluding this break
            break
        if ok == "n" or ok == "N":
            break                   # normal break
    if break_levels:
        break_levels -= 1
        break                       # pop another level
if break_levels:
    break_levels -= 1
    break

# ...and so on

1

নীচের মতো সম্ভবত সামান্য কৌশলটি কার্যক্ষমতায় রিফ্যাক্টরিয়াল পছন্দ না করলে করবে

লুপের শর্তটি নিয়ন্ত্রণ করতে 1 ব্রেক_লেভাল ভেরিয়েবল যুক্ত করা হয়েছে

break_level = 0
# while break_level < 3: # if we have another level of nested loop here
while break_level < 2:
    #snip: print out current state
    while break_level < 1:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": break_level = 2 # break 2 level
        if ok == "n" or ok == "N": break_level = 1 # break 1 level

1

আপনি একটি ভেরিয়েবল (উদাহরণস্বরূপ ব্রেক_স্টেটমেন্ট ) সংজ্ঞায়িত করতে পারেন , তারপরে দ্বি-বিরতি শর্ত দেখা দিলে এটি একটি আলাদা মানতে পরিবর্তন করুন এবং দ্বিতীয় লুপ থেকে বিচ্ছেদ করতে যদি বিবৃতিটি ব্যবহার করেন।

while True:
    break_statement=0
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N": 
            break
        if ok == "y" or ok == "Y": 
            break_statement=1
            break
    if break_statement==1:
        break

ভাল পয়েন্ট, তবে আমাদের আগ্রহের অভ্যন্তরীণ স্তরের উপরে প্রতিটি স্তরের ক্ষেত্রে আমাদের সেই পরিবর্তনশীলটি স্ক্যান করতে হবে। সত্যিই খারাপ লাগছে যে ভাষার কোনও GoTo নির্দেশনা নেই, পারফরম্যান্স-ভিত্তিক।
আনাতোলি আলেক্সেভ

1

আমি আপনাকে স্মরণ করিয়ে করার অধিকার কোড মাঝখানে যে পাইথন ইন ফাংশান তৈরি করা যেতে পারে চাই এবং পড়ার জন্য এবং স্বচ্ছভাবে পার্শ্ববর্তী ভেরিয়েবল অ্যাক্সেস করতে পারেন nonlocalঅথবাglobal লেখার জন্য ঘোষণা।

সুতরাং আপনি "ব্রেকডেবল নিয়ন্ত্রণ কাঠামো" হিসাবে কোনও ফাংশনটি ব্যবহার করতে পারেন, আপনি যে জায়গায় ফিরে যেতে চান তা নির্ধারণ করে:

def is_prime(number):

    foo = bar = number

    def return_here():
        nonlocal foo, bar
        init_bar = bar
        while foo > 0:
            bar = init_bar
            while bar >= foo:
                if foo*bar == number:
                    return
                bar -= 1
            foo -= 1

    return_here()

    if foo == 1:
        print(number, 'is prime')
    else:
        print(number, '=', bar, '*', foo)

>>> is_prime(67)
67 is prime
>>> is_prime(117)
117 = 13 * 9
>>> is_prime(16)
16 = 4 * 4

1

2 উপায়ে সমাধান

উদাহরণ সহ: এই দুটি ম্যাট্রিক কি সমান / সমান?
ম্যাট্রিক্স 1 এবং ম্যাট্রিক্স 2 একই আকার, এন, 2 ডাইমেনশনাল ম্যাট্রিক্স।

ফার্স্ট সল্যুশন , একটি ফাংশন ছাড়া

same_matrices = True
inner_loop_broken_once = False
n = len(matrix1)

for i in range(n):
    for j in range(n):

        if matrix1[i][j] != matrix2[i][j]:
            same_matrices = False
            inner_loop_broken_once = True
            break

    if inner_loop_broken_once:
        break

দ্বিতীয় সমাধান , একটি ফাংশন সহ
এটি আমার ক্ষেত্রে চূড়ান্ত সমাধান

def are_two_matrices_the_same (matrix1, matrix2):
    n = len(matrix1)
    for i in range(n):
        for j in range(n):
            if matrix1[i][j] != matrix2[i][j]:
                return False
    return True

আপনার দিনটি শুভ হোক!


1
# this version breaks up to a certain label

break_label = None
while True:
    # snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y":
            break_label = "outer"   # specify label to break to
            break
        if ok == "n" or ok == "N":
            break
    if break_label:
        if break_label != "inner":
            break                   # propagate up
        break_label = None          # we have arrived!
if break_label:
    if break_label != "outer":
        break                       # propagate up
    break_label = None              # we have arrived!

#do more processing with menus and stuff

0

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

x = True
y = True
while x == True:
    while y == True:
         ok = get_input("Is this ok? (y/n)") 
         if ok == "y" or ok == "Y":
             x,y = False,False #breaks from both loops
         if ok == "n" or ok == "N": 
             break #breaks from just one

0

এখানে কার্যকর হচ্ছে বলে মনে হচ্ছে এমন একটি বাস্তবায়ন:

break_ = False
for i in range(10):
    if break_:
        break
    for j in range(10):
        if j == 3:
            break_ = True
            break
        else:
            print(i, j)

একমাত্র ফিরে আসার বিষয়টি হ'ল break_লুপগুলির আগে আপনাকে সংজ্ঞা দিতে হবে ।


0

কোনও ভাষা স্তর থেকে এটি করার কোনও উপায় নেই। কিছু ভাষায় গোটো থাকে অন্যের বিরতি থাকে যা যুক্তি দেয়, অজগর তা করে না।

সেরা বিকল্পগুলি হ'ল:

  1. একটি পতাকা সেট করুন যা বাইরের লুপ দ্বারা পরীক্ষা করা হয়, বা বাইরের লুপের শর্ত সেট করে।

  2. একটি ফাংশনে লুপটি রাখুন এবং একবারে সমস্ত লুপগুলি ভেঙে ফেলার জন্য রিটার্নটি ব্যবহার করুন।

  3. আপনার যুক্তি সংশোধন করুন।

ক্রেডিট 1987 সাল থেকে প্রোগ্রামার বিবেক নগরাজনকে যায়


ফাংশন ব্যবহার করে

def doMywork(data):
    for i in data:
       for e in i:
         return 

পতাকা ব্যবহার করা হচ্ছে

is_break = False
for i in data:
   if is_break:
      break # outer loop break
   for e in i:
      is_break = True
      break # inner loop break

-3

আগের মতো একই, তবে আরও কমপ্যাক্ট। (বুলিয়ানরা কেবল সংখ্যা)

breaker = False #our mighty loop exiter!
while True:
    while True:
        ok = get_input("Is this ok? (y/n)")
        breaker+= (ok.lower() == "y")
        break

    if breaker: # the interesting part!
        break   # <--- !

2
এটি দেখতে বেশ কুৎসিত দেখাচ্ছে এবং আগেরটির তুলনায় কোডটি বোঝা আরও শক্ত করে তোলে। এছাড়াও, এটা ভুল। ইনপুটটি গ্রহণযোগ্য কিনা এবং 1 লুপের পরে ব্রেক হয়ে যায় কিনা তা আসলে যাচাই করা বাদ দেয় It
এরিক

-3

যেহেতু এই প্রশ্নটি একটি নির্দিষ্ট লুপ ভাঙ্গার জন্য একটি প্রমিত প্রশ্নে পরিণত হয়েছে, তাই আমি উদাহরণ দিয়ে ব্যবহার করে আমার উত্তর দিতে চাই Exception

যদিও একাধিক লুপযুক্ত কনস্ট্রাক্টে লুপ ভাঙার নামকরণের কোনও লেবেল উপস্থিত নেই তবে আমরা আমাদের পছন্দসই একটি নির্দিষ্ট লুপকে ভাঙ্গতে ব্যবহারকারীর সংজ্ঞায়িত ব্যতিক্রমগুলি ব্যবহার করতে পারি । নিম্নলিখিত উদাহরণটি বিবেচনা করুন যেখানে আমাদের বেস -6 নম্বর পদ্ধতিতে 4 সংখ্যা পর্যন্ত সমস্ত সংখ্যা মুদ্রণ করা যাক:

class BreakLoop(Exception):
    def __init__(self, counter):
        Exception.__init__(self, 'Exception 1')
        self.counter = counter

for counter1 in range(6):   # Make it 1000
    try:
        thousand = counter1 * 1000
        for counter2 in range(6):  # Make it 100
            try:
                hundred = counter2 * 100
                for counter3 in range(6): # Make it 10
                    try:
                        ten = counter3 * 10
                        for counter4 in range(6):
                            try:
                                unit = counter4
                                value = thousand + hundred + ten + unit
                                if unit == 4 :
                                    raise BreakLoop(4) # Don't break from loop
                                if ten == 30: 
                                    raise BreakLoop(3) # Break into loop 3
                                if hundred == 500:
                                    raise BreakLoop(2) # Break into loop 2
                                if thousand == 2000:
                                    raise BreakLoop(1) # Break into loop 1

                                print('{:04d}'.format(value))
                            except BreakLoop as bl:
                                if bl.counter != 4:
                                    raise bl
                    except BreakLoop as bl:
                        if bl.counter != 3:
                            raise bl
            except BreakLoop as bl:
                if bl.counter != 2:
                    raise bl
    except BreakLoop as bl:
        pass

যখন আমরা আউটপুট মুদ্রণ করি, আমরা কখনই কোন মান পাব না যার ইউনিট প্লেসটি 4 আছে that সেক্ষেত্রে আমরা কোনও লুপ থেকে ভাঙ্গি না BreakLoop(4) একই লুপে উত্থিত এবং ধরা পড়ে ভাঙি না। একইভাবে, যখনই দশটি স্থানে 3 থাকে তখন আমরা তৃতীয় লুপ ব্যবহার করে বিভক্ত হয়ে যাই BreakLoop(3)। যখনই শত স্থানে 5 রয়েছে তখন আমরা ব্যবহার করে দ্বিতীয় লুপে BreakLoop(2)বিভক্ত হই এবং যখনই হাজার জায়গায় 2 থাকে তখন আমরা ব্যবহার করে প্রথম লুপে বিভক্ত হইBreakLoop(1)

সংক্ষেপে, অভ্যন্তরীণ লুপগুলিতে আপনার ব্যতিক্রম (অন্তর্নির্মিত বা ব্যবহারকারী সংজ্ঞায়িত) উত্থাপন করুন এবং আপনি নিজের নিয়ন্ত্রণটি পুনরায় শুরু করতে চান এমন লুপটিতে এটি ধরুন। আপনি যদি সমস্ত লুপগুলি থেকে বিরতি পেতে চান তবে সমস্ত লুপের বাইরের ব্যতিক্রমটি ধরুন। (উদাহরণস্বরূপ আমি এই মামলাটি দেখাইনি)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.