2009-06-20 19 views
28

Sự khác nhau giữa Iterator và Máy phát điện là gì?Sự khác nhau giữa Iterator và Máy phát điện là gì?

+1

Tôi đang đá bản thân mình vì mất theo dõi các bản sao của tôi sách Griswold trên ngôn ngữ lập trình Biểu tượng. Theo như tôi biết, đó là nơi mà các trình vòng lặp và máy phát điện đầu tiên xuất hiện dưới dạng các tính năng ngôn ngữ và các giải thích rất tuyệt vời. Tất nhiên, đó là hơn 20 năm trước và tôi nghĩ rằng họ sẽ không bao giờ xuất hiện trong bất kỳ ngôn ngữ nào tôi thực sự sử dụng trong sản xuất. Nhưng bây giờ họ đang ở trong Python và đến với JavaScript, vì vậy tôi đoán tôi đã sai. – Nosredna

+1

Tương tự: [Sự khác nhau giữa các bộ tạo và bộ lặp của Python] (http://stackoverflow.com/q/2776829/55075), nhưng đối với Python cụ thể. – kenorb

Trả lời

34

Máy phát điện là bộ lặp, nhưng không phải tất cả các bộ lặp là máy phát.

Trình lặp thường là thứ có phương thức tiếp theo để nhận yếu tố tiếp theo từ luồng. Trình tạo là một trình lặp được gắn với một hàm.

Ví dụ một máy phát điện trong python:

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

này có ưu điểm là bạn không cần phải lưu trữ số vô hạn trong bộ nhớ để lặp qua chúng.

Bạn muốn sử dụng này như bạn làm bất kỳ iterator:

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

Bạn cũng có thể lặp lại trên một mảng:

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

Một máy phát điện là một thực hiện một iterator. Nó thường là một thói quen mang lại nhiều giá trị cho người gọi của nó như trái ngược với chỉ một.

Trong 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

Một iterator đi qua một bộ sưu tập cùng một lúc.

A generator tạo một chuỗi, một mục tại một thời điểm.

Bạn có thể ví dụ, lặp qua các kết quả của một máy phát điện ...

0

thường lặp đi bộ qua một chuỗi hiện có (chẳng hạn như một mảng hoặc danh sách) và máy phát điện tính toán một giá trị mới theo mọi yêu cầu.

+0

Điều này không đúng. Có thể tạo (không có máy phát điện) một Iterator, ví dụ cung cấp hình vuông của mọi số tự nhiên. Không có đối tượng mảng hoặc danh sách hiện có nào được sao lưu. –

+0

Nếu bạn gọi đó là một trình lặp thì sự khác biệt giữa một trình lặp và một trình tạo là gì? –

+0

Sự khác biệt về cơ bản là những gì chưa biết (google) nói. Một "trình tạo là một trình lặp được gắn với một hàm". Tất nhiên, "hàm" thực sự là một máy trạng thái giống như một hàm. Tôi đã cung cấp một ví dụ trong một câu trả lời. –

0

Trình lặp thường được sử dụng để di chuyển qua một tập hợp các mục. Thường có các phương thức MoveNext() và Current(). MoveNext() sẽ chuyển con trỏ đến mục bộ sưu tập tiếp theo (nếu có thể) và trả về true/false dựa trên thành công. Hiện tại() sẽ cung cấp giá trị thực tế.

Máy phát điện là việc triển khai trình lặp, nhưng thay vì trỏ đến một bộ sưu tập đã có, nó tạo các mục mới trên mỗi cuộc gọi MoveNext().

1

Trình lặp được sử dụng để lặp qua các đối tượng trong bộ sưu tập, có thể là một mảng, danh sách được liên kết, cây, bản đồ băm, bất kỳ thứ gì. Bạn đã có một loạt các đối tượng và bạn muốn làm điều gì đó với từng đối tượng.

Máy phát không chỉ trả lại các mục từ một số bộ sưu tập đồ vật hữu hạn. Thay vào đó, nó tạo ra chúng trên bay. Bạn có thể khái niệm hóa nó như là một iterator trên một bộ sưu tập được tạo ra trong khi bạn đang iterating qua nó và có thể không có kích thước hữu hạn. Ví dụ:

Ví dụ, bạn có thể có một trình tạo ra các số nguyên tố từ 2 đến vô cùng. Không có cách nào bạn có thể có một bộ sưu tập "tất cả các số nguyên tố" và lặp lại nó với một trình lặp. Bạn cần một máy phát điện.

Hoặc bạn có thể tạo một trình tạo số nguyên và sinh ra các yếu tố của số một tại một thời điểm. Một máy phát điện sẽ mang lại lợi ích cho bạn ở đây vì bạn có thể kiểm tra từng yếu tố mà không cần phân bổ bộ nhớ cho tất cả các nhân tố trả trước. Nó cũng sẽ cho phép bạn sử dụng chúng khi chúng được tạo ra thay vì phải tạo toàn bộ danh sách lên phía trước, có thể chậm hơn bạn thích. Dưới đây là ví dụ về trình tạo như vậy trong Python:

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

for n in factors(1234567890): 
    print n 

Nếu bạn chạy điều này, bạn có thể thấy các yếu tố được in khi chúng được tính toán. Chúng tôi không cần phải thực sự duy trì toàn bộ danh sách tất cả các yếu tố trong bộ nhớ.

+1

Một lần nữa, điều này là sai. Các bộ lặp không cần phải có bộ sưu tập sao lưu "thực" (mảng, danh sách liên kết, bất kỳ thứ gì). –

4

Máy phát điện là một chức năng đặc biệt có thể hoạt động như một Iterator, trả lại giá trị mỗi khi nó được gọi. Bởi vì nó là một hàm, nó có thể tính toán mỗi giá trị theo yêu cầu. Và bởi vì nó là đặc biệt, nó có thể nhớ trạng thái của nó từ lần cuối cùng nó được gọi, vì vậy mã kết quả trông khá đơn giản.

Ví dụ, máy phát điện này trong python sẽ tạo ra một chuỗi các số nguyên

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

Điều quan trọng trong ví dụ này là báo cáo kết quả yield n. Hàm sẽ trả về giá trị, và lần sau nó được gọi, nó sẽ tiếp tục từ điểm đó.

Liên kết này có một lời giải thích dài hơn máy phát điện trong python: link text

6

Có quá nhiều Python ở đây, và quá nhiều người nói máy phát điện là chỉ cách để thực hiện một iterator vô hạn. Dưới đây là ví dụ tôi đã đề cập (hình vuông của tất cả các số tự nhiên) được triển khai trong C#. ExplicitSquares thực hiện rõ ràng một trình lặp (được gọi là IEnumerator trong C#). ImplicitSquares sử dụng một máy phát điện để làm điều tương tự. Cả hai đều là các trình lặp vô hạn và không có bộ sưu tập sao lưu. Sự khác biệt duy nhất là liệu máy trạng thái có được viết ra hay không, hoặc máy phát điện được sử dụng.

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

(từ useland javascript, nhưng giống như tất cả những người khác)

Một interator là một đối tượng mà có một chức năng .next()

Một máy phát điện là một hàm , một lần được gọi, tạo ra một trình lặp, nó là một nhà máy cho trình vòng lặp.

Trong javascript, chức năng máy phát điện yêu cầu một chức năng cú pháp đặc biệt *() {} và sử dụng cho từ khóa năng suất

Xem MDN về điều này: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

Các vấn đề liên quan