![Featued image for: Copilot Enterprise Introduces Search and Customized Best Practices](https://optimuscloud.com.br/wp-content/uploads/2024/02/Copilot-Enterprise-apresenta-praticas-recomendadas-de-pesquisa-e-personalizadas-150x150.png)
Copilot Enterprise apresenta práticas recomendadas de pesquisa e personalizadas
27 de fevereiro de 2024![Criando um caminho para o sucesso do Prometheus](https://optimuscloud.com.br/wp-content/uploads/2024/02/1709130570_Criando-um-caminho-para-o-sucesso-do-Prometheus-150x150.jpg)
Criando um caminho para o sucesso do Prometheus
28 de fevereiro de 2024No domínio da programação, um gerador é uma rotina usada para controlar a interação dentro de um loop. Os geradores são úteis quando você deseja produzir uma grande sequência de valores sem armazená-los na memória de uma só vez. A capacidade de criar uma sequência grande sem consumir memória é importante, especialmente quando se trata de programas Python que geram uma grande quantidade de informações, como uma longa sequência de números.
Vejamos pi, por exemplo. Você pode criar um programa Python que exija o uso de pi até um determinado ponto decimal, que pode ser bastante grande. Você não gostaria de armazenar todos esses números na memória porque poderia acabar em uma situação em que seu computador (ou o computador no qual o aplicativo será executado) ficaria sem memória disponível. Isto é especialmente verdade considerando o fato de que os decimais de Pi nunca terminam. Então, o que você faz? Você cria um gerador e evita armazenar milhares (ou possivelmente milhões) de números na memória.
De acordo com a documentação do Python, “As funções geradoras permitem declarar uma função que se comporta como um iterador, ou seja, pode ser usada em um loop for.”
Vamos dar uma olhada em uma função geradora muito simples. Este pequeno aplicativo imprimirá uma sequência de números.
Para fazer isso, usaremos a palavra-chave yield, que retorna um objeto gerador (como uma expressão) em vez de simplesmente retornar um valor. Nosso exemplo usará um gerador para imprimir a sequência de Fibonacci. (Terminaremos com 100 números para que você não acabe com muita produção.)
Para quem não sabe, esta sequência é uma série de números onde cada número é a soma dos dois números anteriores – então, 0+1=1, 1+1=2, 1+2=3, 2+3 =5 e assim por diante.
Esta pequena aplicação definirá um gerador chamado fibonacci(n). Nosso gerador fica assim:
def fibonacci(n): a = b = 1 for i in range(n): yield a a, b = b, a + b
A linha “a, b = b, a+b” é usada para calcular a + b antes de atribuir essa soma a b. É um truque bem conhecido de descompactação de tuplas que você pode ler em vários documentos.
Usamos rendimento aqui porque é eficiente em termos de memória (porque a execução acontece apenas quando o chamador itera sobre o objeto).
A seguir, criamos um loop for para imprimir a sequência de Fibonacci para 100 números, assim:
for x in fibonacci(100): print(x)
O aplicativo inteiro fica assim:
def fibonacci(n): a = b = 1 for i in range(n): yield a a, b = b, a + b for x in fibonacci(100): print(x)
Ao executar o aplicativo, ele imprimirá os primeiros 100 números da sequência de Fibonacci.
Claro que podemos fazer isso sem um gerador, mas corremos o risco de esgotar os recursos do sistema.
Voltemos ao nosso exemplo pi. Digamos que você queira criar uma função que calcule pi até a enésima casa decimal, mas não queira correr o risco de essa função consumir todos os recursos do sistema. Como você deve ter adivinhado: para esta tarefa, você precisará criar um gerador.
A primeira coisa que devemos fazer é importar o módulo sys, que fornece as funções e variáveis necessárias para manipular certas partes do ambiente de execução Python:
import sys
A seguir, vamos definir nosso gerador, que chamamos de calcPi(), usando um loop while:
def calcPi(): q, r, t, k, n, l = 1, 0, 1, 1, 3, 3 while True: if 4*q+r-t < n*t: yield n nr = 10*(r-n*t) n = ((10*(3*q+r))//t)-10*n q *= 10 r = nr else: nr = (2*q+r)*l nn = (q*(7*k)+2+(r*l))//(t*l) q *= k t *= l l += 2 k += 1 n = nn r = nr
Nossa próxima seção define uma variável pi_digits usando o gerador calcPi() e, em seguida, usa um loop for para iterar pelos valores de pi_digits:
pi_digits = calcPi() i = 0 for d in pi_digits: sys.stdout.write(str(d)) i += 1 if i == 50: print("") i = 0
Todo o programa fica assim:
import sys def calcPi(): q, r, t, k, n, l = 1, 0, 1, 1, 3, 3 while True: if 4*q+r-t < n*t: yield n nr = 10*(r-n*t) n = ((10*(3*q+r))//t)-10*n q *= 10 r = nr else: nr = (2*q+r)*l nn = (q*(7*k)+2+(r*l))//(t*l) q *= k t *= l l += 2 k += 1 n = nn r = nr pi_digits = calcPi() i = 0 for d in pi_digits: sys.stdout.write(str(d)) i += 1 if i == 50: print("") i = 0
Se você executar este aplicativo, ele continuará imprimindo pi até que você o interrompa manualmente. Se você não tivesse usado um gerador para isso, o aplicativo consumiria rapidamente todos os recursos do sistema e você poderia acabar em uma situação em que teria que reiniciar a máquina.
Nem todo gerador precisa incluir a palavra-chave yield. Veja este exemplo simples que produz os quadrados dos números de 0 a 4. O aplicativo é assim:
squarenum_generator = (i * i for i in range(5)) for i in squarenum_generator: print(i)
O que você vê acima é um objeto gerador que produz números quadrados de 0 * 0 a 4 * 4, seguido por um loop for que itera sobre o gerador para obter os valores gerados. Neste exemplo, o gerador é a primeira linha.
Essa é a verdadeira beleza dos geradores Python. Em vez de correr o risco de causar problemas em todo o sistema, você controla o problema ao não armazenar grandes quantidades de informações.
A postagem Python: como usar uma função geradora apareceu pela primeira vez em The New Stack.