2013-06-16 11 views
7

पायथन के पास for लूप में स्वचालित रूप से काउंटर वैरिएबल उत्पन्न करने का एक शानदार तरीका है: enumerate फ़ंक्शन। यह काउंटर वैरिएबल को आरंभ करने और बढ़ाने की आवश्यकता को बचाता है। काउंटर वैरिएबल भी बदसूरत हैं क्योंकि लूप समाप्त होने के बाद वे अक्सर बेकार होते हैं, फिर भी उनका दायरा लूप का दायरा नहीं है, इसलिए वे बिना किसी आवश्यकता के नेमस्पेस पर कब्जा करते हैं (हालांकि मुझे यकीन नहीं है कि enumerate वास्तव में यह हल करता है)।पाशोनिक गणना जबकि लूप

मेरा सवाल यह है कि क्या while loops के लिए एक समान पायथनिक समाधान है या नहीं। enumeratewhile लूप के लिए काम नहीं करेगा क्योंकि enumerate एक पुनरावर्तक देता है। आदर्श रूप में, समाधान "पायथनिक" होना चाहिए और फ़ंक्शन परिभाषाओं की आवश्यकता नहीं है।

उदाहरण के लिए:

x=0 
c=0 
while x<10: 
    x=int(raw_input()) 
    print x,c 
    c+=1 

इस मामले हम आरंभ और c बढ़ाने से बचने के लिए चाहते हो जाएगा में।

स्पष्टीकरण:

यह मैनुअल समाप्ति के साथ एक अंतहीन for पाश के साथ किया जा सकता है के रूप में कुछ सुझाव दिया है, लेकिन मैं एक समाधान है कि कोड साफ बनाता रहा हूँ, और मुझे नहीं लगता कि उस समाधान इस मामले में कोड स्पष्ट बनाता है।

+5

क्या आप एक उदाहरण दे सकते हैं? आपको थोड़ी देर लूप का उपयोग क्यों करना चाहिए? – BrenBarn

+4

क्या आप कुछ ऐसा ढूंढ रहे हैं [itertools.count?] (Http://docs.python.org/2.7/library/itertools.html#itertools.count) –

+0

क्या आपका मतलब है (i <100) {i ++} दया लूप का? – Darek

उत्तर

6

सुधार:

x = 0 
for c in itertools.takewhile(lambda c: x < 10, itertools.count()): 
    x = int(raw_input()) 
    print x, c 

लाभ:

  • केवल लूप हेडर लूप हेडर में है, न कि दुष्प्रभाव raw_input।
  • लूप स्थिति किसी भी शर्त पर निर्भर हो सकती है जो लूप हो सकता है। टेकवेली में संदर्भित चर को "आयात" करना जरूरी नहीं है, क्योंकि वे पहले से ही लैम्ब्डा स्कोप में दिखाई दे रहे हैं। इसके अतिरिक्त यदि आप चाहते हैं तो यह गिनती पर निर्भर हो सकता है, हालांकि इस मामले में नहीं।
  • सरलीकृत: गणना अब बिल्कुल दिखाई नहीं दे रही है।
+0

अच्छा समाधान। मुझे लगता है कि पठनीयता बहुत अच्छी है। – Bitwise

1

मुझे नहीं लगता कि यह वही करना संभव है जो आप चाहते हैं कि आप चाहते हैं। यदि मैं सही समझता हूं, तो आप while लूप चाहते हैं जो लूप के दायरे से बाहर एक दृश्य काउंटर को उजागर किए बिना हर बार एक काउंटर बढ़ाता है। मुझे लगता है कि ऐसा करने का तरीका आपके while लूप को एक nonterminating for लूप के रूप में फिर से लिखना होगा, और अंत स्थिति को मैन्युअल रूप से जांचें। आपके उदाहरण कोड के लिए:

import itertools 

x = 0 
for c in itertools.count(): 
    x = int(raw_input()) 
    print x, c 
    if x >= 10: 
     break 

समस्या यह है कि मूल रूप से आप काउंटर के साथ पुनरावृत्ति कर रहे हैं। यदि आप उस काउंटर को बेनकाब नहीं करना चाहते हैं, तो इसे लूप निर्माण से आना होगा। एक नए समारोह को परिभाषित किए बिना, आप एक मानक पाश और एक स्पष्ट जांच के साथ अटक गए हैं।

दूसरी ओर, आप शायद इसके लिए जनरेटर भी परिभाषित कर सकते हैं। आप अभी भी पुनरावृत्त हो रहे हैं, लेकिन आप कम से कम लूप निर्माण में चेक अप लपेट सकते हैं।

+0

धन्यवाद। मैं आम तौर पर उस तरह के 'लूप्स' से बचने लगता हूं और मुझे लगता है कि यह बहुत पाइथनिक नहीं है। यह 'बस' और काउंटर वैरिएबल को रखने के लिए शायद स्पष्ट होगा। चलो देखते हैं कि कोई अलग समाधान के साथ आता है या नहीं। – Bitwise

6

फिर से itertools के साथ ...

import itertools 

for c, x in enumerate(
    itertools.takewhile(lambda v: v < 10, 
     (int(raw_input()) for z in itertools.count()) 
    ) 
): 
    print c, x 
+0

दिलचस्प है, लेकिन मैं नहीं कहूंगा कि यह कोड स्पष्ट हो जाता है! :-) – BrenBarn

+1

@ ब्रेनबर्न: यह ..... रिफैक्टरिंग का * बिट * सहन कर सकता है ... –

+0

दरअसल, यह काफी कार्यात्मक रूप से समान नहीं है। मूल कोड 10 या बड़े मान को प्रिंट करेगा, लेकिन यह नहीं होगा। – morningstar

2

यदि आप चाहते हैं शून्य प्रारंभ while पाश से पहले, आप एक Singleton एक काउंटर के साथ उपयोग कर सकते हैं:

class Singleton(object): 
    _instance = None 
    def __new__(cls, *args, **kwargs): 
     if not cls._instance: 
      cls._instance = super(Singleton, cls).__new__(
           cls, *args, **kwargs) 
      cls.count=0 
     else: 
      cls.count+=1        
     return cls._instance 

तो फिर वहाँ केवल सिंगलटन का एक उदाहरण हो जाएगा और प्रत्येक अतिरिक्त उदाहरण सिर्फ कहते हैं एक:

>>> Singleton().count # initial instance 
0 
>>> Singleton().count 
1 
>>> Singleton().count 
2 
>>> Singleton().count 
3 

फिर अपने जबकि पाश हो जाता है:

012,
while Singleton(): 
    x=int(raw_input('x: ')) 
    if x>10: break 

print 'While loop executed',Singleton().count,'times' 

में प्रवेश कर 1,2,3,11 यह प्रिंट:

import collections 
class WhileEnum(collections.Iterator): 
    def __init__(self,stop=None): 
     self.stop=stop 
     self.count=0 

    def next(self): # '__next__' on Py 3, 'next' on Py 2 
     if self.stop is not None: 
      self.remaining=self.stop-self.count 
      if self.count>=self.stop: return False 
     self.count+=1  
     return True 

    def __call__(self): 
     return self.next() 

फिर अपने जबकि पाश:

x: 1 
x: 2 
x: 3 
x: 11 
While loop executed 4 times 

आप while पाश से पहले एक पंक्ति प्रारंभ से परहेज नहीं करते हैं, तो आप सिर्फ एक interator उपवर्ग कर सकते हैं बन जाता है:

enu=WhileEnum() 
while enu(): 
    i=int(raw_input('x: ')) 
    if i>10: break 

print enu.count 

मुझे लगता है कि दूसरा सबसे बेहतर दृष्टिकोण है। आप एक से अधिक प्रगणक हो सकता है और आप भी कितने छोरों जाना पर एक सीमा निर्धारित कर सकते हैं: (पठनीयता में, मैं कहता हूँ चाहते हैं) इग्नेसियो के जवाब देने के लिए

limited_enum=WhileEnum(5) 
+0

दिलचस्प ले, धन्यवाद। – Bitwise

संबंधित मुद्दे