পাইথন: বাইরের লুপে পরবর্তী পুনরাবৃত্তির অবিরত


135

আমি জানতে চেয়েছিলাম পাইথনের বাইরের লুপে পরবর্তী পুনরাবৃত্তিটি চালিয়ে যাওয়ার কোনও অন্তর্নির্মিত উপায় আছে কিনা। উদাহরণস্বরূপ, কোডটি বিবেচনা করুন:

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            continue
    ...block1...

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


11
পাইথনের জন্য প্রকৃতপক্ষে একটি কার্যকরী গেটো স্টেটমেন্ট রয়েছে: এন্ট্রিয়ান ডটকম / গোটো । এটি একটি এপ্রিল বোকাদের রসিকতা হিসাবে প্রকাশিত হয়েছিল :-), তবে কাজ করার কথা।
কোডেপ

3
ওহ, দয়া করে যে গোটো রসিকতা ব্যবহার করবেন না! এটি উল্লেখযোগ্যভাবে চালাক, তবে আপনি যদি আপনার কোডটিতে রাখেন তবে আপনি পরে দুঃখ পাবেন।
নেড ব্যাচেল্ডার

উত্তর:


71
for i in ...:
    for j in ...:
        for k in ...:
            if something:
                # continue loop i

সাধারণ ক্ষেত্রে, যখন আপনার একাধিক স্তরের লুপিং থাকে এবং আপনার breakপক্ষে কাজ করে না (কারণ আপনি উপরের লুপগুলির একটি বর্তমানের উপরের একটির উপরে না চালিয়ে যেতে চান), আপনি নিম্নলিখিতগুলির একটি করতে পারেন

আপনি যে ফাংশন থেকে পালাতে চান সেই লুপগুলি রিফ্যাক্টর

def inner():
    for j in ...:
        for k in ...:
            if something:
                return


for i in ...:
    inner()

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

অথবা আপনি innerনেস্টেড ফাংশন হিসাবে সংজ্ঞায়িত করতে পারেন এবং এটি কেবল যা প্রয়োজন তা ক্যাপচার করতে দিন (ধীর হতে পারে?)

for i in ...:
    def inner():
        for j in ...:
            for k in ...:
                if something:
                    return
    inner()

ব্যতিক্রম ব্যবহার করুন

দার্শনিকভাবে, ব্যতিক্রমগুলির জন্য এটিই রয়েছে, যখন প্রয়োজন হয় কাঠামোগত প্রোগ্রামিং বিল্ডিং ব্লকগুলির (যদি, যখন, তবে) প্রোগ্রামের প্রবাহকে ভঙ্গ করে।

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

এই পদ্ধতির সাথে খারাপ জিনিস হ'ল দোভাষী / সংকলক লেখকরা সাধারণত ধরে নেন যে ব্যতিক্রমগুলি ব্যতিক্রমী এবং সে অনুযায়ী তাদের জন্য অনুকূলিত।

class ContinueI(Exception):
    pass


continue_i = ContinueI()

for i in ...:
    try:
        for j in ...:
            for k in ...:
                if something:
                    raise continue_i
    except ContinueI:
        continue

এর জন্য একটি বিশেষ ব্যতিক্রম শ্রেণি তৈরি করুন, যাতে আপনি দুর্ঘটনাক্রমে অন্য কিছু ব্যতিক্রম স্থগিত করার ঝুঁকি না ফেলে।

পুরোপুরি অন্য কিছু

আমি নিশ্চিত যে এখনও অন্য সমাধান আছে।


বিশ্বাস করা যায় না আমি আমার দ্বিতীয় লুপটি অন্য পদ্ধতিতে সরিয়ে নিয়ে যাওয়ার কথা ভাবিনি। আমি ধীর হয়ে যাচ্ছি
23:25

1
আমার কাছে, ব্যতিক্রমগুলি ব্যবহার করা এটি অর্জনের একটি ভাল উপায়। আমি @ ব্যবহারকারী 7610- এর সাথে একমত - "দার্শনিকভাবে, ব্যতিক্রমগুলি এটাই।"
রেনাটো বাইরো

ভাল পুরাতন বুলিয়ান পরিবর্তনশীল এবং যদি বিবৃতি?
মিঃআর

ওপি তার বিকল্প সমাধানের সন্ধান করছে, "আমি এই যুক্তিটিকে অন্য কোনও উপায়ে (একটি ফ্ল্যাগের ভেরিয়েবল সেট করে) প্রয়োগ করতে পারি [...]"
ব্যবহারকারী 7610

149
for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            break
    else:
        ...block1...

Break অভ্যন্তরীণ লুপটি ভেঙে ফেলবে এবং ব্লক 1 কার্যকর হবে না (এটি কেবল তখনই চলবে যদি অভ্যন্তরীণ লুপটি স্বাভাবিকভাবে বাইরে বের হয়)।


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

3
আমার কাছে এটির মতো মনে হচ্ছে আপনি লুপগুলির সাথে কিছু করার চেষ্টা করছেন যা সেরা উপায়ে
অন্যরকমভাবে পৌঁছানো হবে

হ্যাঁ. এজন্য আমি for..else কাঠামোটি ব্যবহার করিনি। এখন আমার এখনও লুপগুলির প্রয়োজন, তবে আমি নিয়ন্ত্রণ ডাইভার্ট করার জন্য পতাকা চলকগুলি ব্যবহার করব।
সাহাস 11

3
for...elseএটি প্রায়শই একটি দরকারী নির্মাণ, যদিও এটি বিভ্রান্তিকর হতে পারে। কেবল মনে রাখবেন যে elseএই প্রসঙ্গে "বিরতি" নয়।
asmeurer

এটি লুপের মাত্র দুটি স্তরের মধ্যে সীমাবদ্ধ বলে মনে হচ্ছে। আমাকে কয়েকটি কোড আপডেট করতে হবে যার মধ্যে তিনটি নেস্টেড লুপ রয়েছে এবং একটি নতুন গ্রাহকের প্রয়োজনীয়তার অর্থ হ'ল নির্দিষ্ট পরিস্থিতিতে অন্তরতম লুপটির বহিরাগত লুপের পরবর্তী পুনরাবৃত্তি চালিয়ে যাওয়া দরকার need আমি ধরে নিলাম আপনার পরামর্শটি সেই দৃশ্যে প্রযোজ্য হবে না।
ক্যাস্পার্ড

42

অন্যান্য ভাষায় আপনি লুপটি লেবেল করতে পারেন এবং লেবেলযুক্ত লুপটি ভেঙে ফেলতে পারেন। পাইথন এনহান্সমেন্ট প্রোপোজাল (PEP) 3136 পাইথন এইসব যোগ করার প্রস্তাব কিন্তু গাইডো এটি বাতিল :

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

  1. জটিলতা স্থায়ীভাবে ভাষায় যুক্ত হয়েছিল। এটি কেবল সমস্ত পাইথন বাস্তবায়নকেই নয়, প্রতিটি উত্স বিশ্লেষণের সরঞ্জামকে, এছাড়াও অবশ্যই ভাষার জন্য সমস্ত ডকুমেন্টেশনকে প্রভাবিত করে।

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

সুতরাং যদি আপনি এটির জন্যই আশা করেছিলেন যে আপনার ভাগ্য থেকে দূরে, তবে অন্য উত্তরের একটির দিকে নজর দিন কারণ সেখানে ভাল বিকল্প রয়েছে।


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

2
সমস্তই আমাদের
বিডিএফএল

4
এটি একটি উত্তম পাল্টা যুক্তির চেয়ে বেশি লাল-উত্তাপযুক্ত, তবে আমার কাছে মনে হয় যে for-elseনামকরণ করা লুপগুলির চেয়ে আচরণটি আরও জটিল, আরও জটিল এবং আরও জটিল (সম্ভবত একটি সম্পূর্ণ ভুল না হলে) হতে পারে। আমি মনে করি আমি এর চেয়ে আলাদা কীওয়ার্ডটি ব্যবহার করতাম else- সম্ভবত এমন কিছু ভাল resumeহত? আপনি breakলুপ এবং resumeঠিক এর পরে?
আর্টঅফ ওয়ারফেয়ার

5
এটা আমাকে দুঃখিত করেছে. পাইথনকে আমি একই সাথে কীভাবে পছন্দ করি এবং ঘৃণা করি তা আমি বিশ্বাস করতে পারি না। এত সুন্দর, তবুও ডাব্লুটিএফ।
jlh

5
@ jlh আমার জন্য বেশিরভাগ wtf কখনও কখনও আমি মনে করি এটি বৈধ উদ্দেশ্যে নয় বরং আলাদা হতে চায়। এটি তার একটি ভাল উদাহরণ। আমি বেশিরভাগ সময় বাইরের লুপগুলি ভাঙার প্রয়োজনীয়তাটি দেখি।
রিকেলাস

14

আমি মনে করি আপনি এরকম কিছু করতে পারেন:

for ii in range(200):
    restart = False
    for jj in range(200, 400):
        ...block0...
        if something:
            restart = True
            break
    if restart:
        continue
    ...block1...

4
-১: ওপি স্পষ্টভাবে জানিয়েছে যে তারা জানত যে তারা এ জাতীয় কিছু করতে পারে, এবং এটি কেবল স্বীকৃত উত্তরের একটি ম্যাসিয়ার সংস্করণের মতো দেখাচ্ছে (এটি আপনার 8 মাসের আগে পূর্বে রয়েছে, সুতরাং এটি এমনটি হতে পারে না যে আপনি কেবল গ্রহণযোগ্যতা মিস করেছেন উত্তর).
আর্টঅফ ওয়ারফেয়ার

10
গৃহীত উত্তর পরিষ্কার না যদি আপনি দেখেননি করেছি for, elseসামনে (এবং আমি মনে করি এমনকি সবচেয়ে মানুষ আছে যারা তাদের মাথার উপরে বন্ধ মনে করতে পারেন না কিভাবে এটি কাজ করে)।
asmeurer

3

আমি মনে করি এটি অর্জনের অন্যতম সহজ উপায় হ'ল "ব্রেক" স্টেটমেন্টের সাথে "চালিয়ে" প্রতিস্থাপন করা, অর্থাৎ

for ii in range(200):
 for jj in range(200, 400):
    ...block0...
    if something:
        break
 ...block1...       

উদাহরণস্বরূপ, এটি কীভাবে ঠিক চলেছে তা দেখতে এখানে সহজ কোডটি রয়েছে:

for i in range(10):
    print("doing outer loop")
    print("i=",i)
    for p in range(10):
        print("doing inner loop")
        print("p=",p)
        if p==3:
            print("breaking from inner loop")
            break
    print("doing some code in outer loop")

2

এই ধরণের সমস্যা মোকাবেলার আরেকটি উপায় হ'ল ব্যতিক্রম () ব্যবহার করা।

for ii in range(200):
    try:
        for jj in range(200, 400):
            ...block0...
            if something:
                raise Exception()
    except Exception:
        continue
    ...block1...

উদাহরণ স্বরূপ:

for n in range(1,4):
    for m in range(1,4):
        print n,'-',m

ফলাফল:

    1-1
    1-2
    1-3
    2-1
    2-2
    2-3
    3-1
    3-2
    3-3

ধরে নিচ্ছি আমরা এম লুপ থেকে বাইরের এন লুপটিতে ঝাঁপ দিতে চাই যদি মি = 3:

for n in range(1,4):
    try:
        for m in range(1,4):
            if m == 3:
                raise Exception()            
            print n,'-',m
    except Exception:
        continue

ফলাফল:

    1-1
    1-2
    2-1
    2-2
    3-1
    3-2

রেফারেন্সের লিঙ্ক: http://www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python


1

আমরা কিছু খুঁজে পেতে চাই এবং তারপরে অভ্যন্তরীণ পুনরাবৃত্তি থামাতে চাই। আমি একটি পতাকা সিস্টেম ব্যবহার করি।

for l in f:
    flag = True
    for e in r:
        if flag==False:continue
        if somecondition:
            do_something()
            flag=False

আমি জানি না কেন আপনার সমাধানটি হ্রাস করা হয়েছিল; কেউ মূলত একই জিনিস পোস্ট করেছে এবং 10 বার
upvated

স্ট্যাকওভারফ্লো নিয়ে আমি খুব ভাগ্যবান নই।
ইষ্টের

1
সম্ভবত এখানে ইতিমধ্যে এখানে একই জিনিস পোস্ট করা হওয়ায় সম্ভবত আমার ধারণা ... এবং False:continueবিষয়টি হ'ল ... অস্বাভাবিক বিন্যাসকরণ। যেহেতু এটি "প্রাকৃতিক" সিস্টেমে প্রায়শই ঘটনামূলক যেমন আদর্শ হয়, তেমনি উল্লেখযোগ্য পরিমাণে খ্যাতিমান পয়েন্টগুলি সংগ্রহ করতে আপনাকে কেবল কয়েকবার ভাগ্যবান হতে হয়। যাইহোক, আমার "সেরা" উত্তরগুলি সাধারণত সবচেয়ে কম জনপ্রিয় হয়।
ব্যবহারকারী 7610

0

আমি সবেমাত্র এরকম কিছু করেছি। এর জন্য আমার সমাধানটি ছিল একটি তালিকা বোঝার সাথে লুপের জন্য অভ্যন্তরটি প্রতিস্থাপন করা।

for ii in range(200):
    done = any([op(ii, jj) for jj in range(200, 400)])
    ...block0...
    if done:
        continue
    ...block1...

যেখানে ওপেন হ'ল কিছু বুলিয়ান অপারেটর ii এবং jj এর সংমিশ্রণে অভিনয় করছেন। আমার ক্ষেত্রে, যদি কোনও অপারেশন সত্য হয়, আমার হয়ে গেছে।

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

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