Pergunta

Qual é a diferença entre um Iterator e um gerador?

Foi útil?

Solução

Os geradores são iteradores, mas nem todos os iteradores são geradores.

Um iterador é tipicamente algo que tem um próximo método para obter o próximo elemento de um córrego. Um gerador é um iterador que está vinculado a uma função.

Por exemplo, um gerador em python:

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

Isto tem a vantagem de que você não precisa armazenar números infinitos na memória para iterar sobre eles.

Você usaria isso como faria com qualquer iterator:

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

Você também poderia iteração sobre um array:

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

Outras dicas

Um iterador atravessa uma coleção um de cada vez.

gerador gera uma sequência, um item de cada vez.

Você pode, por exemplo, interagir sobre o resultado de um gerador de ...

Há muito Python aqui, e muitas pessoas dizendo geradores são o única maneira de implementar um iterador infinito. Aqui está o exemplo que citei (quadrados de todos os números naturais) implementados em C #. ExplicitSquares implementa explicitamente um iterador (chamado IEnumerator em C #). ImplicitSquares usa um gerador para fazer a mesma coisa. Ambos são infinitas iteradores e não têm coleta de apoio. A única diferença é se a máquina de estado está escrito para fora, ou, alternativamente, um gerador é usado.

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

Um gerador é uma implementação de um iterador. É tipicamente uma rotina que os rendimentos vários valores para seu chamador ao invés de apenas um.

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

entrada See de Wikipedia

A Generator é uma função especial que pode se comportar como um Iterator, retornando um valor cada vez que ele é chamado. Porque é uma função, ele pode computar cada valor na demanda. E porque ele é especial, ele pode lembrar seu estado a partir da última vez que foi chamado, portanto, o código resultante parece muito simples.

Por exemplo, este gerador em python irá produzir uma sequência de números inteiros

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

O importante neste exemplo é a declaração yield n. A função irá retornar o valor, ea próxima vez que for chamado, ele vai continuar a partir desse ponto.

Este link tem uma explicação mais longa de geradores em python: texto do link

(de useland javascript, mas mesmo que todos os outros)

Um interator é uma objeto que tem uma função .next ()

Um gerador é uma função , uma vez invocado, produzir um iterador, é uma fábrica de iterador.

Em javascript, função de gerador requerem uma função sintaxe especial * () {} eo uso para o rendimento palavra-chave

Veja MDN sobre isso: https: //developer.mozilla .org / pt-bR / docs / web / JavaScript / Guia / Iterators_and_Generators

Um iterador é usado para iterar sobre os objetos em uma coleção, seja uma matriz, lista, árvore, mapa de hash, ligada o que quer. Você tem um monte de objetos e você quer fazer alguma coisa com cada um deles.

Um gerador não apenas devolver os itens de algum conjunto finito de objetos. Em vez disso, ele gera-los na mosca. Você poderia conceituá-lo como um iterador sobre uma coleção que é criada enquanto estiver a iteração sobre ele e não pode ter tamanho finito.

Por exemplo, você poderia ter um gerador que cospe números primos de 2 a infinito. Não há nenhuma maneira você poderia ter uma coleção de "todos os números primos" e iterate sobre ele com um iterador. Você precisa de um gerador.

Ou você poderia ter um gerador que leva um inteiro e produz os fatores desse número um de cada vez. Um gerador iria beneficiá-lo aqui como você poderia examinar os fatores um por um, sem alocação de memória para todos os fatores adiantado. Também permitiria que você a usá-los como eles são gerados, em vez de ter que gerar a lista inteira na frente, o que pode ser mais lento do que você gosta. Aqui está um exemplo de como gerador de uma em Python:

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

for n in factors(1234567890):
    print n

Se você executar isso, você pode ver os fatores impressos como eles são calculados. Nós não precisa realmente manter uma lista inteira de todos os fatores em memória.

Um iterador é comumente usado para percorrer uma coleção de itens. Tendo frequentemente moveNext () e métodos correntes (). MoveNext () iria mudar o ponteiro para o próximo item de coleção (se possível) e retornar true / false com base no sucesso. Atual () iria fornecer o valor real.

Um gerador é uma implementação do iterador, mas em vez de apontar para uma coleção pré-existente, ele cria novos itens em cada chamada MoveNext ().

Normalmente iterators andar sobre uma seqüência existente (como uma matriz ou lista) e geradores de calcular um novo valor sobre cada solicitação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top