पायथन पुनरावृत्तियों एक hasNext
विधि नहीं है?
पायथन पुनरावृत्तियों एक hasNext
विधि नहीं है?
जवाबों:
नहीं, ऐसी कोई विधि नहीं है। पुनरावृत्ति का अंत एक अपवाद द्वारा इंगित किया गया है। दस्तावेज देखें ।
unnext()
मैं जाँच करने के बाद पहले तत्व को वापस लाने की कोई विधि थी, तो मैं कोशिश करूँगा कि अगर वह कॉल करके मौजूद है, तो मैं उसे पकड़ लूंगा next()
।
yield
या नहीं)। बेशक, एक एडेप्टर लिखना मुश्किल नहीं है जो परिणाम next()
प्रदान करता है has_next()
और प्रदान करता है और move_next()
।
hasNext()
विधि को लागू करने के लिए किया जा सकता है (उत्पादन, कैश करने और सफलता पर सही होने के लिए, या असफलता पर गलत वापसी)। फिर दोनों hasNext()
और next()
एक आम अंतर्निहित पर निर्भर करेगा getNext()
विधि और कैश की गई मद। मैं वास्तव में यह नहीं देखता कि next()
मानक पुस्तकालय में क्यों नहीं होना चाहिए अगर यह एक एडाप्टर को लागू करना इतना आसान है जो इसे प्रदान करता है।
next()
और hasNext()
विधि को प्रभावित करती है , न कि केवल एक काल्पनिक पायथन पुस्तकालय को)। तो हां, next()
और hasNext()
अगर ट्रिक की सामग्री स्कैन की जा रही है तो यह निर्भर करता है कि तत्वों को कब पढ़ा जाता है।
का StopIteration
उपयोग करके एक विकल्प है next(iterator, default_value)
।
निर्वासन के लिए:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
None
यदि आप अपवाद के तरीके को नहीं चाहते हैं, तो आप पुनरावृत्त के अंत के लिए या अन्य पूर्व-निर्दिष्ट मान का पता लगा सकते हैं।
sentinel = object()
और next(iterator, sentinel)
साथ परीक्षण कर सकते हैं is
।
unittest.mock.sentinel
वस्तु का उपयोग करूंगा जो आपको एक स्पष्ट next(a, sentinel.END_OF_ITERATION)
और फिर लिखने की अनुमति देता हैif next(...) == sentinel.END_OF_ITERATION
यदि आपको वास्तव में एक कार्यक्षमता की आवश्यकता है has-next
(क्योंकि आप जावा में संदर्भ कार्यान्वयन से एक एल्गोरिदम का ईमानदारी से रूपांतरण कर रहे हैं, तो कहिए, या क्योंकि आप एक प्रोटोटाइप लिख रहे हैं जिसे समाप्त होने पर आसानी से जावा में स्थानांतरित करना होगा), यह आसान है इसे थोड़ा रैपर क्लास के साथ प्राप्त करें। उदाहरण के लिए:
class hn_wrapper(object):
def __init__(self, it):
self.it = iter(it)
self._hasnext = None
def __iter__(self): return self
def next(self):
if self._hasnext:
result = self._thenext
else:
result = next(self.it)
self._hasnext = None
return result
def hasnext(self):
if self._hasnext is None:
try: self._thenext = next(self.it)
except StopIteration: self._hasnext = False
else: self._hasnext = True
return self._hasnext
अब कुछ ऐसा है
x = hn_wrapper('ciao')
while x.hasnext(): print next(x)
का उत्सर्जन करता है
c
i
a
o
जैसी ज़रूरत।
ध्यान दें कि next(sel.it)
एक अंतर्निहित अंतर्निहित पायथन 2.6 या बेहतर की आवश्यकता होती है; यदि आप पायथन के पुराने संस्करण का उपयोग कर रहे हैं, तो self.it.next()
इसके बजाय का उपयोग करें (और next(x)
उदाहरण के उपयोग के लिए इसी तरह )। [[आप यथोचित रूप से सोच सकते हैं कि यह नोट निरर्थक है, क्योंकि पायथन २.६ अब एक साल से अधिक समय से है - लेकिन अधिक बार नहीं जब मैं एक प्रतिक्रिया में पायथन २.६ सुविधाओं का उपयोग करता हूं, कुछ टिप्पणीकार या अन्य को इंगित करने के लिए ड्यूटी-बाउंड लगता है वे कहते हैं कि कर रहे हैं 2.6 सुविधाओं, इस प्रकार मैं एक बार ;-)]] के लिए इस तरह की टिप्पणियां रोकने के लिए कोशिश कर रहा हूँ
has_next
विधि की आवश्यकता का सबसे खराब कारण है । पायथन के डिजाइन से यह कहना, असंभव हो जाता है कि filter
किसी सरणी में दिए गए एलीमेंट से मेल खाता तत्व है या नहीं। अजगर समुदाय का अहंकार और अदूरदर्शिता चौंका देने वाला है।
TypeError: iter() returned non-iterator
map
और any
इसके बजाय filter
, लेकिन आप उपयोग कर सकते हैं SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINEL
या एक भूल सकते हैं SENTINEL
और बस उपयोग कर सकते हैं try: except
और पकड़ सकते हैं StopIteration
।
StopIteration के सभी उल्लेखों के अलावा, "पाश" के लिए पायथन बस वही करता है जो आप चाहते हैं:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
किसी भी वस्तु वस्तु से __length_hint __ () विधि आज़माएं:
iter(...).__length_hint__() > 0
__init__
और __main__
? Imho, यह एक गड़बड़ का कोई फर्क नहीं पड़ता कि आप इसे सही ठहराने की कोशिश करते हैं।
hasNext
StopIteration
अपवाद के लिए कुछ अनुवाद , उदाहरण के लिए:
>>> it = iter("hello")
>>> it.next()
'h'
>>> it.next()
'e'
>>> it.next()
'l'
>>> it.next()
'l'
>>> it.next()
'o'
>>> it.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
StopIteration
डॉक्स: http://docs.python.org/library/exception.html#exception.StopIterationनहीं। सबसे समान अवधारणा सबसे अधिक संभावना है एक स्टॉपइंटरेशन अपवाद।
मेरा मानना है कि अजगर सिर्फ अगले () और डॉक्टर के अनुसार, यह एक अपवाद फेंकता है और कोई तत्व नहीं हैं।
उपयोग मामला जो मुझे इसके लिए खोज करने के लिए प्रेरित करता है वह निम्नलिखित है
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
try:
x = next(fi)
except StopIteration:
fi = iter(f)
x = next(fi)
self.a[i] = x
जहाँ hasnext () उपलब्ध है, कोई भी कर सकता है
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
if not hasnext(fi):
fi = iter(f) # restart
self.a[i] = next(fi)
जो मेरे लिए क्लीनर है। जाहिर है कि आप उपयोगिता वर्गों को परिभाषित करके मुद्दों के आसपास काम कर सकते हैं, लेकिन फिर क्या होता है आपके पास बीस-विषम अलग-अलग लगभग समतुल्य वर्कअराउंडों में से प्रत्येक का उनके प्रसार के साथ प्रसार होता है, और यदि आप कोड का पुन: उपयोग करना चाहते हैं जो विभिन्न वर्कआउट का उपयोग करता है, तो आपको या तो करना होगा आपके एकल अनुप्रयोग में कई निकट-समतुल्य हैं, या समान दृष्टिकोण का उपयोग करने के लिए कोड के माध्यम से और फिर से लिखना शुरू करते हैं। 'इसे एक बार करें और अच्छी तरह से करें' मैक्सिम बुरी तरह से विफल हो जाता है।
इसके अलावा, इट्रेटर को एक आंतरिक 'हैसनेक्स्ट' चेक की आवश्यकता होती है, यह देखने के लिए कि क्या उसे अपवाद बढ़ाने की आवश्यकता है। यह आंतरिक जांच तब छिपाई जाती है ताकि किसी वस्तु को पाने की कोशिश करके, अपवाद को पकड़कर और फेंकने पर हैंडलर को चलाकर परीक्षण किया जा सके। यह अनावश्यक छुपाने वाला IMO है।
सुझाव दिया रास्ता StopIteration है । कृपया ट्यूटोरियल स्पॉट से फाइबोनैचि उदाहरण देखें
#!usr/bin/python3
import sys
def fibonacci(n): #generator function
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(5) #f is iterator object
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
जिस तरह से मैंने अपनी समस्या को हल किया है वह यह है कि अब तक पुनरावृत्त वस्तुओं की संख्या को ध्यान में रखा जाए। मैं एक उदाहरण विधि के लिए कॉल का उपयोग करते हुए एक सेट पर पुनरावृति करना चाहता था। चूंकि मुझे सेट की लंबाई पता थी, और अब तक गिने जाने वाले आइटमों की संख्या, मेरे पास प्रभावी रूप से एक hasNext
विधि थी।
मेरे कोड का एक सरल संस्करण:
class Iterator:
# s is a string, say
def __init__(self, s):
self.s = set(list(s))
self.done = False
self.iter = iter(s)
self.charCount = 0
def next(self):
if self.done:
return None
self.char = next(self.iter)
self.charCount += 1
self.done = (self.charCount < len(self.s))
return self.char
def hasMore(self):
return not self.done
बेशक, उदाहरण एक खिलौना है, लेकिन आपको यह विचार मिलता है। यह उन मामलों में काम नहीं करेगा, जहां चलने योग्य की लंबाई प्राप्त करने का कोई तरीका नहीं है, जैसे जनरेटर आदि।