{ "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": {} } ] }