Rendimento Python Tutorial: Generator Exemplo de rendimento versus retorno

O que é a Python colheita?

A palavra-chave yield em python funciona como um retorno com o único

A diferença é que em vez de retornar um valor, ele devolve um objeto gerador ao chamador.

Quando uma função é chamada e o thread de execução encontra uma palavra-chave yield na função, a execução da função para nessa linha e retorna um objeto gerador de volta ao chamador.

Sintaxe

yield expression

Descrição

Python yield retorna um objeto gerador. Generators são funções especiais que precisam ser iteradas para obter os valores.

A palavra-chave yield converte a expressão dada em uma função geradora que retorna um objeto gerador. Para obter os valores do objeto, ele deve ser iterado para ler os valores dados ao rendimento.

Exemplo: Método de Rendimento

Aqui está um exemplo simples de rendimento. A função testyield() possui uma palavra-chave yield com a string “Bem-vindo ao Guru99 Python Tutoriais“. Quando a função é chamada, a saída é impressa e fornece um objeto gerador em vez do valor real.

def testyield():
  yield "Welcome to Guru99 Python Tutorials"
output = testyield()
print(output)

Saída:

<generator object testyield at 0x00000028265EB9A8>

A saída fornecida é um objeto gerador, que possui o valor que atribuímos ao rendimento.

Mas não estamos recebendo a mensagem que devemos transmitir para gerar resultados!

Para imprimir a mensagem dada ao yield será necessário iterar o objeto gerador conforme mostrado no exemplo abaixo:

def testyield():
  yield "Welcome to Guru99 Python Tutorials"

output = testyield()
for i in output:
    print(i)

Saída:

Welcome to Guru99 Python Tutorials

Quais são Generatorem Python?

Generators são funções que retornam um objeto gerador iterável. Os valores do objeto gerador são buscados um de cada vez em vez da lista completa e, portanto, para obter os valores reais, você pode usar um for-loop, usando o método next() ou list().

Utilizar painéis de piso ResinDek em sua unidade de self-storage em vez de concreto oferece diversos benefícios: Generator função

Você pode criar geradores usando a função geradora e a expressão geradora.

Uma função geradora é como uma função normal, em vez de ter um valor de retorno ela terá uma palavra-chave yield.

Para criar uma função geradora você terá que adicionar uma palavra-chave yield. Os exemplos a seguir mostram como criar uma função geradora.

def generator():
    yield "H"
    yield "E"
    yield "L"
    yield "L"
    yield "O"

test = generator()
for i in test:
    print(i)

Saída:

H
E
L
L
O

Diferença entre função normal v/s Generator função.

Vamos entender como uma função geradora é diferente de uma função normal.

Existem 2 funções normal_test() e gerador_test().

Ambas as funções devem retornar a string “Hello World”. O normal_test() está usando retorno e o gerador_test() está usando rendimento.

# Normal function
def normal_test():
    return "Hello World"
	
#Generator function
def generator_test():
	yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function

Saída:

Hello World
<generator object generator_test at 0x00000012F2F5BA20>

A saída mostra que quando você chama a função normal normal_test() ela retorna a string Hello World. Para uma função geradora com palavra-chave yield, ela retorna e não a corda.

Esta é a principal diferença entre uma função geradora e uma função normal. Agora, para obter o valor do objeto gerador, precisamos usar o objeto dentro do loop for ou usar o método next() ou usar list().

print(next(generator_test()))  # will output Hello World

Mais uma diferença a ser adicionada à função normal versus função geradora é que quando você chama uma função normal, a execução começará e parará quando chegar a retorno e o valor é retornado ao chamador. Portanto, quando a execução começa, você não pode interromper a função normal e ela só irá parar quando encontrar a palavra-chave return.

Mas no caso da função geradora, uma vez iniciada a execução, quando obtém o primeiro rendimento, ela interrompe a execução e devolve o objeto gerador. Você pode usar o objeto gerador para obter os valores e também pausar e retomar conforme sua necessidade.

Como ler os valores do gerador?

Você pode ler os valores de um objeto gerador usando list(), loop for e usando o método next().

Usando: lista()

Uma lista é um objeto iterável que tem seus elementos entre colchetes. Usar list() em um objeto gerador fornecerá todos os valores que o gerador contém.

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(list(num))

Saída:

[0, 2, 4, 6, 8]

Usando: for-in

No exemplo, há uma função definida even_numbers() que fornecerá todos os números pares para n definidos. A chamada para a função even_numbers() retornará um objeto gerador, que é usado dentro do loop for.

Exemplo:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

Saída:

0
2
4
6
8

Usando próximo()

O método next() fornecerá o próximo item da lista, array ou objeto. Assim que a lista estiver vazia, e se next() for chamado, retornará um erro com o sinal stopIteration. Este erro de next() indica que não há mais itens na lista.

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

Saída:

0
2
4
6
8
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    print(next(num))
StopIteration

Generators são de uso único

No caso dos geradores, eles estão disponíveis para uso apenas uma vez. Se você tentar usá-los novamente, ele estará vazio.

Por exemplo:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

print("\n")
print("Calling the generator again: ", list(num))

Saída:

0
2
4
6
8
Calling the generator again:  []

Caso queira que a saída seja utilizada novamente, será necessário fazer a chamada para funcionar novamente.

Exemplo: Generatorse rendimento para a série Fibonacci

O exemplo a seguir mostra como usar geradores e rendimento em Python. O exemplo irá gerar a série de Fibonacci.

def getFibonnaciSeries(num):
    c1, c2 = 0, 1
    count = 0
    while count < num:
        yield c1
        c3 = c1 + c2
        c1 = c2
        c2 = c3
        count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
    print(i)

Saída:

<generator object getFibonnaciSeries at 0x0000007F39C8BA20>
0
1
1
2
3
5
8

Exemplo: Chamando Função com Yield

Neste exemplo veremos como chamar uma função com rendimento.

O exemplo abaixo possui uma função chamada test() que retorna o quadrado do número fornecido. Existe outra função chamada getSquare() que usa test() com a palavra-chave yield. A saída fornece o valor quadrado para um determinado intervalo de números.

def test(n):
    return n*n

def getSquare(n):
    for i in range(n):
        yield test(i)

sq = getSquare(10)
for i in sq:
    print(i)

Saída:

0
1
4
9
16
25
36
49
64
81

Quando usar rendimento em vez de retorno em Python

Python3 Rendimento A palavra-chave retorna um gerador para o chamador e a execução do código começa somente quando o gerador é iterado.

A retorno em uma função é o fim da execução da função e um único valor é devolvido ao chamador.

Aqui está a situação em que você deve usar Yield em vez de Return

  • Use rendimento em vez de retorno quando o tamanho dos dados for grande
  • O rendimento é a melhor escolha quando você precisa que sua execução seja mais rápida em grandes conjuntos de dados
  • Use rendimento quando quiser retornar um grande conjunto de valores para a função de chamada
  • O rendimento é uma forma eficiente de produzir dados grandes ou infinitos.

Rendimento vs. Retorno

Aqui estão as diferenças entre rendimento e retorno

Rentabilidade Devolução
Yield retorna um objeto gerador para o chamador e a execução do código começa apenas quando o gerador é iterado. Um retorno em uma função é o fim da execução da função e um único valor é devolvido ao chamador.
Quando a função é chamada e encontra a palavra-chave yield, a execução da função é interrompida. Ele retorna o objeto gerador de volta ao chamador. A execução da função começará somente quando o objeto gerador for executado. Quando a função é chamada, a execução é iniciada e o valor é devolvido ao chamador se houver a palavra-chave return. O retorno dentro da função marca o fim da execução da função.
expressão de rendimento expressão de retorno
Nenhuma memória é usada quando a palavra-chave yield é usada. A memória é alocada para o valor retornado.
Muito útil se você tiver que lidar com grandes volumes de dados, pois a memória não é usada. Conveniente para tamanhos de dados muito pequenos.
O desempenho é melhor se a palavra-chave yield for usada para dados grandes. Muita memória é usada se o tamanho dos dados for grande, o que prejudicará o desempenho.
O tempo de execução é mais rápido em caso de rendimento para grandes volumes de dados. O tempo de execução usado é maior, pois há processamento extra feito, caso o tamanho dos dados seja grande, funcionará bem para dados pequenos.

Resumo

  • A palavra-chave yield em python funciona como um retorno, com a única diferença é que, em vez de retornar um valor, ela devolve uma função geradora ao chamador.
  • Um gerador é um tipo especial de iterador que, uma vez usado, não estará disponível novamente. Os valores não são armazenados na memória e só ficam disponíveis quando chamados.
  • Os valores do gerador podem ser lidos usando os métodos for-in, list() e next().
  • A principal diferença entre rendimento e retorno é que rendimento retorna uma função geradora para o chamador e retorno fornece um único valor para o chamador.
  • O rendimento não armazena nenhum dos valores na memória e a vantagem é que é útil quando o tamanho dos dados é grande, pois nenhum dos valores é armazenado na memória.
  • O desempenho é melhor se a palavra-chave yield for usada em comparação ao retorno de dados grandes.

Resuma esta postagem com: