यदि रेंज () Python 3.3 में जनरेटर है, तो मैं एक सीमा पर अगला () कॉल क्यों नहीं कर सकता?


84

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

myrange = range(10)
print(next(myrange))

मुझे यह त्रुटि देता है:

TypeError: 'range' object is not an iterator

मुझे यहां क्या समझ नहीं आ रहा है? मैं 0 प्रिंट करने के लिए, और अगले मूल्य में आगे बढ़ने की उम्मीद कर रहा था myrange। मैं पायथन के लिए नया हूं, इसलिए कृपया मूल प्रश्न के लिए मेरी क्षमा याचना स्वीकार करें, लेकिन मुझे कहीं और अच्छी व्याख्या नहीं मिली।


2
पुनरावृत्तियों और चीजों के बीच अंतर के लिए stackoverflow.com/q/13054057/395760 देखें जिसे आप forलूप में ओवररेट कर सकते हैं ।

1
क्या यह कहना सही होगा कि जनरेटर पुनरावृत्त होते हैं, लेकिन पुनरावृत्त नहीं?
जेफ

4
@ जेफ़ इटरेबल्स ऐसी वस्तुएं हैं जिनका उपयोग इट्रेटर iterप्राप्त करने के लिए किया जा सकता है। Iterators ऐसी वस्तुएं हैं जिनका उपयोग करके पुनरावृत्त किया जा सकता है next। जनरेटर पुनरावृत्तियों (जनरेटर कार्यों और जनरेटर अभिव्यक्तियों) की एक श्रेणी है। कम से कम मुझे तो यही लगता है ...
ओलेह प्रिनपिन

जवाबों:


109

rangeअपरिवर्तनीय चलने योग्य वस्तुओं का एक वर्ग है। उनके पुनरावृत्ति व्यवहार की तुलना lists से की जा सकती है : आप nextसीधे उन पर कॉल नहीं कर सकते ; आपको इटरेटर का उपयोग करके प्राप्त करना होगा iter

तो नहीं, rangeजेनरेटर नहीं है।

आप सोच रहे होंगे, "उन्होंने इसे सीधे चलने योग्य क्यों नहीं बनाया"? खैर, rangeकुछ उपयोगी गुण हैं जो इस तरह से संभव नहीं होंगे:

  • वे अपरिवर्तनीय हैं, इसलिए उन्हें शब्दकोश कुंजियों के रूप में उपयोग किया जा सकता है।
  • वे start, stopऔर stepविशेषताएं (अजगर 3.3 के बाद से), countऔर indexतरीकों और उनके द्वारा समर्थित in, lenऔर __getitem__आपरेशनों।
  • आप एक ही rangeसमय में एक से अधिक पुनरावृति कर सकते हैं ।

>>> myrange = range(1, 21, 2)
>>> myrange.start
1
>>> myrange.step
2
>>> myrange.index(17)
8
>>> myrange.index(18)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 18 is not in range
>>> it = iter(myrange)
>>> it
<range_iterator object at 0x7f504a9be960>
>>> next(it)
1
>>> next(it)
3
>>> next(it)
5

11
rangeवस्तुओं की एक और अच्छी विशेषता यह है कि उनके पास एक ऐसा __contains__तरीका है जिसका उपयोग यह परीक्षण करने के लिए किया जा सकता है कि मूल्य एक सीमा में है:5 in range(10) => True
kindall

जवाब के लिए धन्यवाद; यह अब समझ में आता है। केवल एक चीज जिसे मैं आपके उत्तर को स्वीकार करने से पहले स्पष्ट करना चाहता हूं, इस पृष्ठ के नीचे एक तिहाई तरीके से इटैलिक में नोट है , जिसमें कहा गया है कि "पायथन 3 रेंज () में एक जनरेटर है"। क्या यह बस गलत है?
जेफ

3
@ जेफ सख्त बोल, हां, यह गलत है। नोट के लेखक शायद मतलब है कि अजगर 3 में rangeहै आलसी (अजगर 2 की तुलना में जहां यह सिर्फ एक समारोह है कि रिटर्न एक सूची है)।
ओलेह प्रिनपिन

6
इसके अलावा: range(0,10,3)[3]और 9 in range(0,10,3)। रेंज बहुत अधिक एक आलसी सूची है।
लेनार्ट रेगेब्रॉ

2
@ user3079275 "सीधे चलने योग्य" एक मिथ्या नाम है, जिसका अर्थ वास्तव में "पुनरावृति" है। Iterators आंतरिक स्थिति है और इसलिए परिभाषा के अनुसार परस्पर भिन्न हैं। "निष्क्रिय" एक वस्तु है, चाहे वह उत्परिवर्तनीय हो या न हो, जो एक पुनरावृत्ति उत्पन्न कर सकती है। यहां तक ​​कि उत्परिवर्तित वस्तुएं आमतौर पर पुनरावृत्तियां खुद नहीं होती हैं, इसके बजाय वे पुन: प्रयोज्य तरीके से पुनरावृत्तियों का उत्पादन करते हैं (उदाहरण के लिए, आप दो पुनरावृत्तियों का उपयोग करके स्वतंत्र रूप से एक ही सूची में दो अलग-अलग स्थानों पर पुनरावृति कर सकते हैं)।
ओलेह प्रीपिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.