В чем разница между Итератором и Генератором?

В чем разница между Итератором и Генератором?

Ответ 1

Генераторы являются итераторами, но не все итераторы являются генераторами.

Итератором обычно является то, что имеет следующий метод для получения следующего элемента из потока. Генератор - это итератор, привязанный к функции.

Например, генератор в python:

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

Это имеет то преимущество, что вам не нужно хранить бесконечные числа в памяти, чтобы перебирать их.

Вы использовали бы это, как и любой итератор:

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

Вы также можете перебирать массив:

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

Ответ 2

iterator обходит коллекцию по одному.

A generator генерирует последовательность, по одному элементу за раз.

Вы можете, например, перебрать результат генератора...

Ответ 3

Здесь слишком много Python, и слишком много людей, говорящих о генераторах, - единственный способ реализовать бесконечный итератор. Вот пример, который я упомянул (квадраты всех натуральных чисел), реализованные в С#. ExplicitSquares явно реализует итератор (называемый IEnumerator в С#). 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);
        }
    }
}

Ответ 4

Генератор - это реализация итератора. Обычно это процедура, которая дает несколько значений своему вызывающему абоненту, а не только одному.

В С#

// 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);
    }
}
}

См. запись в Википедии

Ответ 5

Генератор - это специальная функция, которая может вести себя как Итератор, возвращая значение при каждом вызове. Поскольку это функция, она может вычислять каждое значение по требованию. И поскольку он особенный, он может запомнить свое состояние с момента последнего вызова, поэтому полученный код выглядит довольно простым.

Например, этот генератор в python будет генерировать последовательность целых чисел

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

В этом примере важна инструкция yield n. Функция вернет значение, и в следующий раз, когда она будет вызвана, она будет продолжена с этой точки.

Эта ссылка имеет более длинное объяснение генераторов в python: текст ссылки

Ответ 6

(из javascript useland, но так же, как и все остальные)

Interator - это объект, который имеет функцию .next()

Генератор - это функция, после вызова которой вызывается итератор, а для итератора.

В javascript для функции генератора требуется специальная синтаксическая функция *() {} и использование ключевого слова yield

Смотрите MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

Ответ 7

Итератор используется для итерации по объектам в коллекции, будь то массив, связанный список, дерево, хэш-карта, что угодно. У вас есть куча объектов, и вы хотите что-то сделать с каждым из них.

Генератор не просто возвращает элементы из некоторого конечного набора объектов. Вместо этого он генерирует их на лету. Вы могли бы концептуализировать его как итератор над коллекцией, которая создается во время итерации по ней и может не иметь конечного размера.

Например, у вас может быть генератор, который выплескивает простые числа от 2 до бесконечности. Невозможно собрать коллекцию "всех простых чисел" и перебрать ее с помощью итератора. Вам нужен генератор.

Или у вас может быть генератор, который принимает целое число и дает коэффициенты этого числа по одному за раз. Генератор принесет вам пользу, так как вы можете исследовать факторы один за другим, не выделяя память для всех факторов заранее. Это также позволит вам использовать их по мере их создания, а не создавать весь список вверх, что может быть медленнее, чем вам нравится. Вот пример такого генератора в Python:

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

for n in factors(1234567890):
    print n

Если вы запустите это, вы можете увидеть факторы, напечатанные по мере их расчета. Нам не нужно фактически поддерживать весь список всех факторов в памяти.

Ответ 8

Обычно итераторы просматривают существующую последовательность (например, массив или список), а генераторы вычисляют новое значение при каждом запросе.

Ответ 9

Итератор обычно используется для перемещения по набору элементов. Часто имеют методы MoveNext() и Current(). MoveNext() переместит указатель на следующий элемент коллекции (если возможно) и вернет true/false на основе успеха. Current() будет предоставлять фактическое значение.

Генератор - это реализация итератора, но вместо указания на уже существующий коллекцию он создает новые элементы для каждого вызова MoveNext().