2012-08-10 16 views
10

के लिए एक में पुनरावृत्तियों की संख्या बदलने मैं इस तरह कोड है:पाश

loopcount = 3 
for i in range(1, loopcount) 
    somestring = '7' 
    newcount = int(somestring) 
    loopcount = newcount 

तो क्या मैं चाहता हूँ के लिए 'अंदर' पाश की सीमा को संशोधित करने के लिए है।

मैंने यह कोड लिखा था कि लूप की सीमा पहले लूप के दौरान (1,7) में बदल जाएगी, लेकिन ऐसा नहीं हुआ।

इसके बजाए, कोई फर्क नहीं पड़ता कि मैं किस संख्या में डालता हूं, यह केवल 2 बार चलता है। (मैं इस मामले में 6 बार .. चाहते हैं)

मैं मूल्य इस तरह प्रिंट का उपयोग कर जांच की गई:

loopcount = 3 
    for i in range(1, loopcount) 
     print loopcount 
     somestring = '7' 
     newcount = int(somestring) 
     loopcount = newcount 
     print loopcount 
#output: 
3 
7 
7 
7 

क्या गलत है? संख्या बदल दी गई है।

मेरी सोच गलत कहां है?

+0

हाँ, यह पाश अंदर से सीमा बदलने के लिए संभव है, नीचे नया जवाब देखें। –

उत्तर

23

श्रृंखला के लिए सरल किया जा सकता है कि यह कहा जाता है समय में loopcount के मूल्य के आधार पर बनाई गई है अप्रासंगिक। अगर बयान है कि इसमें चलाता

loopcount = 3 
i = 1 
while i < loopcount: 
    somestring = '7' 
    loopcount = int(somestring) 
    i += 1 

while परीक्षण है कि हालत i < loopcount सच है, और अगर सच है, क्या आप शायद चाहते हैं थोड़ी देर के बयान है। इस मामले में, लूप के माध्यम से प्रत्येक पास पर, मुझे 1 से बढ़ाया जाता है क्योंकि लूपकाउंट पहली बार 7 पर सेट हो जाता है, इसलिए लूप छह गुना चलाएगा, क्योंकि मैं = 1,2,3,4,5 और 6

एक बार स्थिति गलत होने पर, i = 7, जबकि लूप चलने के लिए समाप्त हो जाता है।

(मुझे नहीं पता कि आपका वास्तविक उपयोग केस क्या है, लेकिन आपको न्यूकाउंट असाइन करने की आवश्यकता नहीं है, इसलिए मैंने इसे हटा दिया)।

+2

धन्यवाद –

+0

पर एक बार फिर से चलते समय स्वचालित वृद्धि के अनुकरण के लिए 'i + = 1' के साथ समाप्त होना चाहिए। यह अब बदल गया है। –

+0

मेरे पास इसके अंदर कई सारे कोड हैं यदि परिणाम और i + = 1 का उपयोग करते हैं तो परिणाम में कोई बदलाव नहीं होगा? –

9

range() docstring से:

रेंज ([शुरू,] रोक [, कदम]) -> पूर्णांक

वापसी पूर्णांकों का एक अंकगणितीय प्रगति युक्त एक सूची की सूची। रेंज (i, j) रिटर्न [i, i + 1, i + 2, ..., j-1]; प्रारंभ (!) को 0 पर डिफ़ॉल्ट करें जब चरण दिया जाता है, यह वृद्धि (या कमी) निर्दिष्ट करता है। उदाहरण के लिए, रेंज (4) रिटर्न [0, 1, 2, 3]। अंत बिंदु छोड़ा गया है! ये 4 तत्वों की सूची के लिए बिल्कुल मान्य सूचकांक हैं।

तो, range(1, 10), उदाहरण के लिए, की तरह एक सूची प्रस्तुत करती है: [1,2,3,4,5,6,7,8,9], हां, तो आपके कोड मूल रूप से कर रही है:

loopcount = 3 
for i in [1, 2]: 
    somestring = '7' 
    newcount = int(somestring) 
    loopcount = newcount 

जब आपके for लूप "प्रारंभ" है, सूची range() द्वारा बनाई गई है ।

+0

आह! मै समझता हुँ! लेकिन फिर मैं लूप 'अंदर' रेंज कैसे बदलूं? क्या मैं यह नहीं कर सकता –

+2

यदि आपको अपनी लूप सीमाओं को संशोधित करने की आवश्यकता है, तो मैं आपको सुझाव देता हूं कि आप उसे 'while'' के साथ कोड करें, जैसा कि @ user802500 द्वारा सुझाया गया है। –

1

range() फ़ंक्शन का मूल्यांकन for में किया जाता है -लूप यह मानों का अनुक्रम उत्पन्न करता है (यानी एक सूची) जिसका उपयोग फिर से करने के लिए किया जाएगा।

range() इस के लिए loopcount के मान का उपयोग करता है। हालांकि, एक बार कि अनुक्रम उत्पन्न हुआ है, के अंदर कुछ भी नहीं है, लूप उस सूची को बदल देगा, यानी यदि आप loopcount बाद में बदलते हैं, तो मूल सूची वही रहेगी => पुनरावृत्तियों की संख्या वही रहेगी ।

आपके मामले में:

loopcount = 3 
for i in range(1, loopcount): 

, दो बार

for i in [1, 2]: 

तो अपने पाश दोहराता हो जाता है के बाद से आप पाश उत्पादन के अपने get 4 लाइनों में 2 print बयान है। ध्यान दें कि आप loopcount का मान प्रिंट कर रहे हैं जो प्रारंभ में 3 है, लेकिन उसके बाद सेट (और रीसेट) 7 हो जाता है।

यदि आप पुनरावृत्ति संख्या को बदलने में सक्षम होना चाहते हैं तो गतिशील रूप से while -loop का उपयोग करने पर विचार करें। बेशक आप break कथन के उपयोग के साथ जल्दी से किसी भी लूप को रोक/बाहर निकाल सकते हैं। कुछ भी है कि बाद में है loopcount के लिए होता -

इसके अलावा,

somestring = '7' 
    newcount = int(somestring) 

सिर्फ

newcount = 7 
1

ऐसा लगता है कि आपके आधार पर यह है कि आपके पास लूप को निष्पादित करने की डिफ़ॉल्ट संख्या है, लेकिन कभी-कभार स्थिति जहां यह अलग होती है। यह बजाय एक समय पाश का उपयोग करना बेहतर हो सकता है, लेकिन परवाह किए बिना तुम सिर्फ कर सकते हैं:

if i == some_calculated_threshold: 
    break 

बजाय लूप से बाहर ड्रॉप करने।

+1

-1; मूल प्रश्न लूप के माध्यम से 2 से 7 तक की संख्या बढ़ाने की कोशिश कर रहा है; मदद करने के लिए 'ब्रेक 'कैसा है? – geoffspear

0

आप नहीं वृद्धि पुनरावृत्तियों की संख्या एक बार सीमा निर्धारित किया गया है सकते हैं, लेकिन आप जल्दी बाहर तोड़ सकता है, जिससे पुनरावृत्तियों की संख्या कम:

for i in xrange(1, 7): 
    if i == 2: 
     break 
2

विशेष रूप से प्रश्न के समाधान के लिए "कैसे मैं सीमा सीमा बदल सकता हूँ ", आप send method for a generator का लाभ ले सकते:

def adjustable_range(start, stop=None, step=None): 
    if stop is None: 
     start, stop = 0, start 

    if step is None: step = 1 

    i = start 
    while i < stop: 
     change_bound = (yield i) 
     if change_bound is None: 
      i += step 
     else: 
      stop = change_bound 

उपयोग:

myrange = adjustable_range(10) 

for i in myrange: 
    if some_condition: 
     myrange.send(20) #generator is now bounded at 20 
+2

+1, हालांकि यह जनरेटर * अभिव्यक्ति * नहीं है - बस एक जनरेटर। – lvc

+0

@ एलवीसी: ओह, संपादित। –

+0

आप अपना कोड चलाने का प्रयास करना चाहेंगे। मैंने इस पृष्ठ पर पोस्ट किए गए किसी अन्य के साथ अपना संस्करण ठीक करने का प्रयास किया। –

0

जोएल कॉर्नेट द्वारा प्रदत्त adjustable_range फ़ंक्शन का एक और पूर्ण कार्यान्वयन है।

def adjustable_range(start, stop=None, step=None): 
    if not isinstance(start, int): 
     raise TypeError('start') 
    if stop is None: 
     start, stop = 0, start 
    elif not isinstance(stop, int): 
     raise TypeError('stop') 
    direction = stop - start 
    positive, negative = direction > 0, direction < 0 
    if step is None: 
     step = +1 if positive else -1 
    else: 
     if not isinstance(step, int): 
      raise TypeError('step') 
     if positive and step < 0 or negative and step > 0: 
      raise ValueError('step') 
    if direction: 
     valid = (lambda a, b: a < b) if positive else (lambda a, b: a > b) 
     while valid(start, stop): 
      message = yield start 
      if message is not None: 
       if not isinstance(message, int): 
        raise ValueError('message') 
       stop = message 
      start += step 
3

जबकि लूप जवाब द्वारा user802500 अपने वास्तविक समस्या का सबसे अच्छा समाधान होने की संभावना है दिया; हालांकि, मुझे लगता है कि प्रश्न के रूप में एक दिलचस्प और निर्देशक उत्तर है।

रेंज() कॉल का परिणाम निरंतर मूल्यों की एक सूची है। फॉर-लूप उस सूची में तब तक पुनरावृत्ति करता है जब तक यह समाप्त नहीं हो जाता है।

यहां मुख्य बिंदु है: आपको पुनरावृत्ति के दौरान सूची को म्यूट करने की अनुमति है।

>>> loopcount = 3 
>>> r = range(1, loopcount) 
>>> for i in r: 
     somestring = '7' 
     newcount = int(somestring) 
     del r[newcount:] 

इस स्थान का एक व्यावहारिक उपयोग एक कार्यसूची में कार्य से अधिक पुनरावृत्ति और कुछ कार्यों के नए सब उत्पन्न करने के लिए अनुमति दे रहा है:

for task in tasklist: 
    newtask = do(task) 
    if newtask: 
     tasklist.append(newtask) 
+0

सूची के लिए उत्परिवर्तनीय होने का उपयोग करने की अच्छी चाल। तो, मुझे लगता है कि स्थिति में कुछ तत्वों को हटाने के लिए 'डेल' का उपयोग करने के बजाय, नई सूची मूल सूची आकार से बड़ी है, हम 'एपेंड' का उपयोग करेंगे। – ntough