2009-06-20 11 views
28

इटरेटर और जेनरेटर के बीच क्या अंतर है?इटरेटर और जेनरेटर के बीच क्या अंतर है?

+1

मैं अपने आप को मेरी नकल का ट्रैक खोने के लिए लात कर रहा हूँ आइकन प्रोग्रामिंग भाषा पर ग्रिसवॉल्ड की पुस्तक का। जहां तक ​​मुझे पता है, वही है जहां इटेटर और जनरेटर पहली बार भाषा विशेषताओं के रूप में दिखाई देते थे, और स्पष्टीकरण महान थे। बेशक, यह 20 साल पहले था और मुझे लगा कि वे कभी भी किसी भी भाषा में दिखाई नहीं देंगे जो मैं वास्तव में उत्पादन में उपयोग करता हूं। लेकिन अब वे पाइथन में हैं और जावास्क्रिप्ट पर आ रहे हैं, इसलिए मुझे लगता है कि मैं गलत था। – Nosredna

+1

इसी तरह: [पायथन के जेनरेटर और इटरेटर्स के बीच अंतर] (http://stackoverflow.com/q/2776829/55075), लेकिन पाइथन विशिष्ट के लिए। – kenorb

उत्तर

34

जनरेटर इटरेटर हैं, लेकिन सभी इटरेटर जनरेटर नहीं हैं।

एक पुनरावर्तक आमतौर पर कुछ है जो अगले विधि से एक धारा से प्राप्त करने के लिए विधि है। एक जनरेटर एक पुनरावर्तक है जो किसी फ़ंक्शन से बंधे होते हैं।

उदाहरण के लिए अजगर में एक जनरेटर:

def genCountingNumbers(): 
    n = 0 
    while True: 
    yield n 
    n = n + 1 

यह लाभ है कि आप स्मृति में अनंत संख्या स्टोर करने के लिए उन पर पुनरावृति करने की जरूरत नहीं है।

आप जैसे आप किसी भी इटरेटर इस का उपयोग करेंगे:

for i in ['a', 'b', 'c']: 
    print i 
5

एक जनरेटर पुनरावर्तक के एक कार्यान्वयन है:

for i in genCountingNumbers(): 
    print i 
    if i > 20: break # Avoid infinite loop 

तुम भी एक सरणी से अधिक पुनरावृति सकता है। यह आम तौर पर एक दिनचर्या है जो अपने कॉलर को केवल एक के विपरीत कई मूल्य उत्पन्न करता है।

C#

// yield-example.cs 
using System; 
using System.Collections; 
public class List 
{ 
    public static IEnumerable Power(int number, int exponent) 
    { 
     int counter = 0; 
     int result = 1; 
     while (counter++ < exponent) 
     { 
      result = result * number; 
      yield return result; 
    } 
} 

static void Main() 
{ 
    // Display powers of 2 up to the exponent 8: 
    foreach (int i in Power(2, 8)) 
    { 
     Console.Write("{0} ", i); 
    } 
} 
} 

See Wikipedia's entry

37

एक iterator में एक समय में एक संग्रह एक को पार करता।

generator एक समय में एक अनुक्रम, एक आइटम उत्पन्न करता है।

आप उदाहरण के लिए, एक जनरेटर के परिणाम पर पुनरावृति सकती है ...

0

आमतौर पर iterators एक मौजूदा अनुक्रम (जैसे किसी सरणी या सूची के रूप में) पर चलने और जनरेटर हर अनुरोध पर एक नया मूल्य की गणना।

+0

यह सही नहीं है। एक इटरेटर के बिना (जनरेटर के बिना) बनाना संभव है कि उदाहरण के लिए प्रत्येक प्राकृतिक संख्या का वर्ग प्रदान करता है। इसका समर्थन करने वाला कोई मौजूदा सरणी या सूची ऑब्जेक्ट नहीं है। –

+0

यदि आप इसे एक पुनरावर्तक कहते हैं तो एक पुनरावर्तक और जनरेटर के बीच क्या अंतर है? –

+0

अंतर मूल रूप से अज्ञात (google) ने कहा है। ए "जनरेटर एक पुनरावर्तक है जो किसी फ़ंक्शन से जुड़ा हुआ है"। बेशक, "फ़ंक्शन" वास्तव में एक राज्य मशीन है जो फ़ंक्शन की तरह दिखती है। मैंने एक जवाब में एक उदाहरण प्रदान किया है। –

0

एक पुनरावर्तक आमतौर पर वस्तुओं के संग्रह के माध्यम से स्थानांतरित करने के लिए उपयोग किया जाता है। अक्सर MoveNext() और वर्तमान() विधियां होती हैं। MoveNext() पॉइंटर को अगले संग्रह आइटम (यदि संभव हो) में स्थानांतरित कर देगा और सफलता के आधार पर सही/गलत लौटाएगा। वर्तमान() वास्तविक मूल्य प्रदान करेगा।

एक जनरेटर पुनरावर्तक का कार्यान्वयन है, लेकिन पूर्व-मौजूदा संग्रह को इंगित करने के बजाय, यह प्रत्येक MoveNext() कॉल पर नए आइटम बनाता है।

1

एक पुनरावर्तक को संग्रह में वस्तुओं पर फिर से चलाने के लिए उपयोग किया जाता है, चाहे वह एक सरणी, लिंक्ड सूची, पेड़, हैश नक्शा, जो भी हो। आपके पास वस्तुओं का एक गुच्छा है और आप उनमें से प्रत्येक के साथ कुछ करना चाहते हैं।

एक जनरेटर वस्तुओं के कुछ सीमित संग्रह से वस्तुओं को वापस नहीं करता है। इसके बजाय, यह उन्हें फ्लाई पर उत्पन्न करता है। आप इसे पर बनाए गए संग्रह पर एक पुनरावर्तक के रूप में अवधारणा बना सकते हैं, जबकि आप इसे पर पुन: सक्रिय कर रहे हैं और सीमित आकार नहीं हो सकता है।

उदाहरण के लिए, आपके पास एक जनरेटर हो सकता है जो प्राइम संख्याओं को 2 से अनंत तक थका देता है। ऐसा कोई तरीका नहीं है कि आप "सभी प्राइम नंबर" का संग्रह कर सकें और इसे एक इटरेटर के साथ फिर से चालू कर सकें। आपको जनरेटर की आवश्यकता है।

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

def factors(n): 
    for i in xrange(1, n+1): 
     if n % i == 0: 
      yield i 

for n in factors(1234567890): 
    print n 

: यहाँ अजगर में इस तरह के एक जनरेटर का एक उदाहरण है। हमें स्मृति में सभी कारकों की पूरी सूची को वास्तव में बनाए रखने की आवश्यकता नहीं है।

+1

फिर, यह गलत है। Iterators के पास "वास्तविक" बैकिंग संग्रह (सरणी, लिंक की गई सूची, जो भी हो) नहीं है। –

4

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

उदाहरण के लिए, अजगर में इस जनरेटर पूर्णांकों

def integers(): 
    int n = 0 
    while True: 
     yield n 
     n += 1 

इस उदाहरण में महत्वपूर्ण बात यह है yield n बयान है के अनुक्रम का उत्पादन करेगा। फ़ंक्शन मान वापस कर देगा, और अगली बार इसे कॉल किया जाएगा, यह उस बिंदु से जारी रहेगा।

यह लिंक अजगर में जनरेटर की एक लंबी व्याख्या है: link text

6

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

using System.Collections; 
using System.Collections.Generic; 
using System; 

class ExplicitSquares : IEnumerable<int> 
{ 
    private class ExplicitSquaresEnumerator : IEnumerator<int> 
    { 
     private int counter = 0; 

     public void Reset() 
     { 
      counter = 0; 
     } 

     public int Current { get { return counter * counter; }} 

     public bool MoveNext() 
     { 
      counter++; 
      return true; 
     } 

     object IEnumerator.Current { get { return Current; } } 

     public void Dispose(){} 
    } 

    public IEnumerator<int> GetEnumerator() 
    { 
     return new ExplicitSquaresEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

class ImplicitSquares : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() 
    { 
     int counter = 1; 
     while(true) 
     { 
      int square = counter * counter; 
      yield return square; 
      counter++; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public class AllSquares 
{ 
    private static readonly int MAX = 10; 

    public static void Main() 
    { 
     int i = 0; 
     foreach(int square in new ExplicitSquares()) 
     { 
      i++; 
      if(i >= MAX) 
       break; 
      Console.WriteLine(square); 
     } 

     Console.WriteLine(); 

     int j = 0; 
     foreach(int square in new ImplicitSquares()) 
     { 
      j++; 
      if(j >= MAX) 
       break; 
      Console.WriteLine(square); 
     } 
    } 
} 
2

(जावास्क्रिप्ट useland से, फिर भी सभी दूसरों के रूप में ही)

एक interator एक वस्तु एक .next() फ़ंक्शन है कि

एक जनरेटर एक समारोह, एक बार है आह्वान किया, एक इटरेटर का उत्पादन, यह इटरेटर के लिए एक कारखाना है।

जावास्क्रिप्ट में, जनरेटर समारोह की आवश्यकता होती है एक विशेष वाक्य रचना समारोह *() {} और उपज कीवर्ड

इस पर MDN देखें के लिए उपयोग: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

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