दिलचस्प पोस्ट
Android प्रोजेक्ट में ड्रैगर से निर्भरता इंजेक्शन कैसे सेट अप करें? मैं यूनिक्स कमांड लाइन पर या किसी शेल स्क्रिप्ट में पाठ फ़ाइल की लाइनों को कैसे फेर सकती हूँ? सी में डबल पॉन्टर कॉन्स्ट-अचुरता चेतावनी CSS3 संक्रमण: "संक्रमण: सभी" "संक्रमण:" से धीमी है? कैसे अपने अंकों के संरक्षण के लिए गोल करने के लिए पूर्णांक के लिए गोलियां? समाप्त करने के लिए "किसी भी प्रक्रिया" के लिए प्रतीक्षा करें सी # में एक संदर्भ के बजाय प्रतिलिपि को कैप्चर करने के लिए लैम्ब्डा फंक्शन को कैसे बताना है? मैं जावास्क्रिप्ट में 2 फ़ंक्शन की तुलना कैसे करूं? किसी सामग्री के तत्व में एचटीएमएल के साथ चयनित पाठ को कैसे बदलना है? मैं आईओएस एप्लिकेशन के भीतर से यूट्यूब में एक वीडियो कैसे अपलोड करूं? जावास्क्रिप्ट में मैं राइट-क्लिक इवेंट कैसे कैप्चर कर सकता हूं? Parameters.Add और Parameters.AddWithValue के बीच अंतर फ़ॉर्म के बाहर माउस / कीबोर्ड ईवेंट कैप्चर करना (पृष्ठभूमि में चलने वाला ऐप) डेटा फ़ोल्डर में कैमरा के रूप में एक यूरी कैसे प्राप्त करें? कैसे एक <iframe> में एक पीडीएफ फाइल खोलने के लिए?

पायथन जनरेटर में एक तत्व कैसे दिखता है?

मैं समझ नहीं सकता कि पायथन जनरेटर में एक तत्व को कैसे देखना है। जैसे ही मुझे लगता है कि यह चला गया है

यही है जो मेरा मतलब है:

gen = iter([1,2,3]) next_value = gen.next() # okay, I looked forward and see that next_value = 1 # but now: list(gen) # is [2, 3] -- the first value is gone! 

यहाँ एक और अधिक वास्तविक उदाहरण है:

 gen = element_generator() if gen.next_value() == 'STOP': quit_application() else: process(gen.next()) 

क्या कोई मुझे जनरेटर लिखने में मदद करता है कि आप एक तत्व को आगे देख सकते हैं?

वेब के समाधान से एकत्रित समाधान "पायथन जनरेटर में एक तत्व कैसे दिखता है?"

पायथन जनरेटर एपीआई एक तरीका है: आप अपने द्वारा पढ़े गए तत्वों को वापस नहीं धकेल सकते हैं। लेकिन आप आईटेरोलॉज मॉड्यूल का उपयोग करके एक नया इरेरेटर बना सकते हैं और तत्व में शामिल हो सकते हैं:

 import itertools gen = iter([1,2,3]) peek = gen.next() print list(itertools.chain([peek], gen)) 

पूर्णता के लिए, more-itertools पैकेज (जो कि किसी भी पायथन प्रोग्रामर के टूलबॉक्स का हिस्सा होना चाहिए) में इस व्यवहार को लागू करने वाले एक peekable आवरण शामिल हैं दस्तावेज़ीकरण में कोड का उदाहरण दिखाता है:

 >>> p = peekable(xrange(2)) >>> p.peek() 0 >>> p.next() 0 >>> p.peek() 1 >>> p.next() 1 

पैकेज दोनों पायथन 2 और 3 के साथ संगत है, भले ही प्रलेखन अजगर 2 वाक्यविन्यास दिखाते हैं।

ठीक है – दो साल बहुत देर हो चुकी हैं – लेकिन मैं इस प्रश्न पर आया, और मेरी संतुष्टि के जवाब में से कोई भी नहीं मिला। इस मेटा जनरेटर के साथ आया:

 class Peekorator(object): def __init__(self, generator): self.empty = False self.peek = None self.generator = generator try: self.peek = self.generator.next() except StopIteration: self.empty = True def __iter__(self): return self def next(self): """ Return the self.peek element, or raise StopIteration if empty """ if self.empty: raise StopIteration() to_return = self.peek try: self.peek = self.generator.next() except StopIteration: self.peek = None self.empty = True return to_return def simple_iterator(): for x in range(10): yield x*3 pkr = Peekorator(simple_iterator()) for i in pkr: print i, pkr.peek, pkr.empty 

का परिणाम:

 0 3 False 3 6 False 6 9 False 9 12 False ... 24 27 False 27 None False 

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

आप जेनरेटर की हल्के प्रतिलिपि बनाने के लिए आईटेरोटोल्स.टेई का उपयोग कर सकते हैं। फिर एक प्रति पर आगे बढ़ते हुए दूसरी प्रति प्रभावित नहीं करेगा:

 import itertools copy1, copy2 = itertools.tee(original_generator) if copy1.next() == "STOP": stop_application() process_items(copy2) 

'Copy2' जनरेटर आपके द्वारा 'copy1' के साथ छेड़छाड़ नहीं कर रहा है ध्यान दें कि आपको उस पर 'टी' कॉल करने के बाद 'मूल-निर्माता' का उपयोग नहीं करना चाहिए, जो चीजों को तोड़ देगा।

एफडब्ल्यूआईडब्ल्यू, इस समस्या को सुलझाने का गलत तरीका है। कोई भी एल्गोरिथम जिसकी आवश्यकता है कि जनरेटर में आगे 1 आइटम देखने के लिए वैकल्पिक रूप से वर्तमान जनरेटर आइटम और पिछली आइटम का उपयोग करने के लिए लिखा जा सकता है। इसके बाद आपको जनरेटर के इस्तेमाल के लिए मर्जल नहीं करना पड़ता है और आपका कोड बहुत सरल होगा। इस सवाल का मेरा दूसरा जवाब देखें

बस मज़े के लिए, मैंने हारून द्वारा दिए गए सुझाव के आधार पर एक लेटरहाइड क्लास का कार्यान्वयन बनाया:

 import itertools class lookahead_chain(object): def __init__(self, it): self._it = iter(it) def __iter__(self): return self def next(self): return next(self._it) def peek(self, default=None, _chain=itertools.chain): it = self._it try: v = self._it.next() self._it = _chain((v,), it) return v except StopIteration: return default lookahead = lookahead_chain 

इसके साथ, निम्नलिखित कार्य करेगा:

 >>> t = lookahead(xrange(8)) >>> list(itertools.islice(t, 3)) [0, 1, 2] >>> t.peek() 3 >>> list(itertools.islice(t, 3)) [3, 4, 5] 

इस कार्यान्वयन के साथ एक पंक्ति में कई बार झांकना कॉल करने का एक बुरा विचार है …

सीपीआईथॉन स्रोत कोड को देखते हुए मुझे बस एक बेहतर तरीका मिला है जो दोनों कम और अधिक कुशल है:

 class lookahead_tee(object): def __init__(self, it): self._it, = itertools.tee(it, 1) def __iter__(self): return self._it def peek(self, default=None): try: return self._it.__copy__().next() except StopIteration: return default lookahead = lookahead_tee 

उपयोग उपरोक्त के समान है, लेकिन आप एक पंक्ति में कई बार झांकना का उपयोग करने के लिए यहां एक मूल्य का भुगतान नहीं करेंगे। कुछ और पंक्तियों के साथ आप इटरेटर में एक से अधिक आइटम को देख सकते हैं (उपलब्ध RAM तक)

 >>> gen = iter(range(10)) >>> peek = next(gen) >>> peek 0 >>> gen = (value for g in ([peek], gen) for value in g) >>> list(gen) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

आइटम (i, i + 1) का उपयोग करने के बजाय, जहां 'आई' वर्तमान वस्तु है और I + 1 'आगे बढ़ना' संस्करण है, आपको (i-1, i) का उपयोग करना चाहिए, जहां 'i-1' जनरेटर से पिछले संस्करण है

अपने एल्गोरिदम को छूने से इस तरह से कुछ उत्पन्न होगा जो आपके पास वर्तमान में मौजूद है, 'आगे बढ़ने' की कोशिश करने की अतिरिक्त अनावश्यक जटिलता के अलावा

आगे बढ़ना एक गलती है, और आपको ऐसा नहीं करना चाहिए।

यह काम करेगा – यह एक आइटम को बफर करता है और प्रत्येक आइटम के साथ एक फ़ंक्शन कॉल करता है और अगले आइटम को क्रम में कहते हैं।

अनुक्रम के अंत में जो कुछ होता है, उसके बारे में आपकी आवश्यकताओं को संदिग्ध है। जब आप आखिरी बार होते हैं तो "आगे देखें" क्या होता है?

 def process_with_lookahead( iterable, aFunction ): prev= iterable.next() for item in iterable: aFunction( prev, item ) prev= item aFunction( item, None ) def someLookaheadFunction( item, next_item ): print item, next_item 

एक सरल समाधान इस तरह से एक फ़ंक्शन का उपयोग करना है:

 def peek(it): first = next(it) return first, itertools.chain([first], it) 

तब आप कर सकते हैं:

 >>> it = iter(range(10)) >>> x, it = peek(it) >>> x 0 >>> next(it) 0 >>> next(it) 1 

हालांकि itertools.chain() नौकरी के लिए प्राकृतिक उपकरण है, यहां इस तरह के छोरों से सावधान रहें:

 for elem in gen: ... peek = next(gen) gen = itertools.chain([peek], gen) 

… क्योंकि यह स्मृति की एक रैंकिक रूप से बढ़ती मात्रा का उपभोग करेगी, और अंततः एक थकावट में पीस सकता है। (यह कोड अनिवार्य रूप से एक लिंक्ड सूची, एक नोड प्रति चेन () कॉल बनाने लगता है।) मुझे यह पता नहीं है क्योंकि मैंने लिब्स का निरीक्षण किया था, लेकिन क्योंकि यह मेरे प्रोग्राम के प्रमुख मंदी के परिणामस्वरूप – gen = itertools.chain([peek], gen) से छुटकारा पा रहा था gen = itertools.chain([peek], gen) लाइन फिर से इसे तेज कर दी (पायथन 3.3)

@ जोनाथन-हार्टले के लिए अजगर 3 स्निपेट उत्तर:

 def peek(iterator, eoi=None): iterator = iter(iterator) try: prev = next(iterator) except StopIteration: return iterator for elm in iterator: yield prev, elm prev = elm yield prev, eoi for curr, nxt in peek(range(10)): print((curr, nxt)) # (0, 1) # (1, 2) # (2, 3) # (3, 4) # (4, 5) # (5, 6) # (6, 7) # (7, 8) # (8, 9) # (9, None) 

यह एक वर्ग बनाने के लिए सरल होगा जो इसे __iter__ पर करता है और केवल prev आइटम पैदा करता है और elm को कुछ विशेषता में डालता है।

यदि कोई दिलचस्पी है, और मुझे गलत कर दें, तो मुझे सही करें, लेकिन मेरा मानना ​​है कि किसी भी पुनरावर्तक को कुछ पुश वापस कार्यक्षमता जोड़ना बहुत आसान है।

 class Back_pushable_iterator: """Class whose constructor takes an iterator as its only parameter, and returns an iterator that behaves in the same way, with added push back functionality. The idea is to be able to push back elements that need to be retrieved once more with the iterator semantics. This is particularly useful to implement LL(k) parsers that need k tokens of lookahead. Lookahead or push back is really a matter of perspective. The pushing back strategy allows a clean parser implementation based on recursive parser functions. The invoker of this class takes care of storing the elements that should be pushed back. A consequence of this is that any elements can be "pushed back", even elements that have never been retrieved from the iterator. The elements that are pushed back are then retrieved through the iterator interface in a LIFO-manner (as should logically be expected). This class works for any iterator but is especially meaningful for a generator iterator, which offers no obvious push back ability. In the LL(k) case mentioned above, the tokenizer can be implemented by a standard generator function (clean and simple), that is completed by this class for the needs of the actual parser. """ def __init__(self, iterator): self.iterator = iterator self.pushed_back = [] def __iter__(self): return self def __next__(self): if self.pushed_back: return self.pushed_back.pop() else: return next(self.iterator) def push_back(self, element): self.pushed_back.append(element) def main(): it = Back_pushable_iterator(x for x in range(10)) x = next(it) # 0 print(x) it.push_back(x) x = next(it) # 0 print(x) x = next(it) # 1 print(x) x = next(it) # 2 y = next(it) # 3 print(x) print(y) it.push_back(y) it.push_back(x) x = next(it) # 2 y = next(it) # 3 print(x) print(y) for x in it: print(x) # 4-9 if __name__ == "__main__": main()