{
"metadata": {
"name": "Capitulo15_Geradores"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
"===================================\n",
"2ª edi\u00e7\u00e3o, revisada e ampliada\n",
"-----------------------------------\n",
"\n",
"Cap\u00edtulo 15: Geradores\n",
"=============================\n",
"_____________________________\n",
"As fun\u00e7\u00f5es geralmente seguem o fluxo convencional de processar, retornar valores e encerrar. Geradores funcionam de forma similar, por\u00e9m lembram o estado do processamento entre as chamadas, permanecendo em mem\u00f3ria e retornando o pr\u00f3ximo item esperado quando ativados.\n",
"\n",
"Os geradores apresentam v\u00e1rias vantagens em rela\u00e7\u00e3o \u00e0s fun\u00e7\u00f5es convencionais:\n",
"\n",
"+ *Lazy Evaluation*: geradores s\u00f3 s\u00e3o processados quando \u00e9 realmente necess\u00e1rio, sendo assim, economizam recursos de processamento.\n",
"+ Reduzem a necessidade da cria\u00e7\u00e3o de listas.\n",
"+ Permitem trabalhar com sequ\u00eancias ilimitadas de elementos.\n",
"\n",
"Geradores geralmente s\u00e3o evocados atrav\u00e9s de um la\u00e7o *for*. A sintaxe \u00e9 semelhante a da fun\u00e7\u00e3o tradicional, s\u00f3 que a instru\u00e7\u00e3o *yield* substitui o *return*. A nova cada itera\u00e7\u00e3o, *yield* retorna o pr\u00f3ximo valor.\n",
"\n",
"Exemplo:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def gen_pares():\n",
" \"\"\"\n",
" Gera n\u00fameros pares entre 0 e 20\n",
" \"\"\"\n",
" i = 0\n",
"\n",
" while i <= 20:\n",
" yield i\n",
" i += 2\n",
"\n",
"# Mostra cada n\u00famero e passa para o pr\u00f3ximo\n",
"for n in gen_pares():\n",
" print n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"2\n",
"4\n",
"6\n",
"8\n",
"10\n",
"12\n",
"14\n",
"16\n",
"18\n",
"20\n"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Outro exemplo:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import os\n",
"\n",
"# Encontra arquivos recursivamente\n",
"def find(path='.'):\n",
"\n",
" for item in os.listdir(path):\n",
" fn = os.path.normpath(os.path.join(path, item))\n",
"\n",
" if os.path.isdir(fn):\n",
"\n",
" for f in find(fn):\n",
" yield f\n",
"\n",
" else:\n",
" yield fn\n",
"\n",
"# A cada itera\u00e7\u00e3o, o gerador devolve\n",
"# um novo nome de arquivo\n",
"for fn in find():\n",
" print fn"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Capitulo15_Geradores.ipynb\n",
"libpeerconnection.log\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Existem v\u00e1rios geradores que fazem parte da pr\u00f3pria linguagem, como o builtin xrange(). Al\u00e9m disso, no m\u00f3dulo *itertools*, est\u00e3o definidos v\u00e1rios geradores \u00fateis.\n",
"\n",
"Para converter a sa\u00edda do gerador em uma lista:\n",
"\n",
" lista = list(gerador())\n",
"\n",
"Assim, todos os itens ser\u00e3o gerados de uma vez."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"\n",
""
],
"output_type": "pyout",
"prompt_number": 1,
"text": [
""
]
}
],
"prompt_number": 1
}
],
"metadata": {}
}
]
}