Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Luciano Ramalho                      luciano@ramalho.org                              @ramalhoorgIteráveis, geradores & ci...
Luciano Ramalho                              luciano@ramalho.org                                      @ramalhoorgIteráveis...
Comparando: C e Python#include <stdio.h>int main(int argc, char *argv[]) {    int i;    for(i = 0; i < argc; i++)        p...
Iteração em Javaclass Argumentos {    public static void main(String[] args) {        for (int i=0; i < args.length; i++) ...
Iteração em Java ≥1.5                        ano:                                             2004 • Enhanced for (for mel...
ano:1990!
Exemplos de iteração• Iteração em Python não se limita a tipos primitivos• Exemplos • string • arquivo • Django QuerySet  ...
>>> from django.db import connection>>> q = connection.queries>>> q[]>>> from municipios.models import *>>> res = Municipi...
Em Python o comando foritera sobre... “iteráveis”• Definicão preliminar informal: • “iterável” = que pode ser iterado • ass...
List comprehensionList comprehensions          ●   Compreensão de lista ou abrangência                             ●   Exe...
Set & dict comprehensions• Expressões que consomem iteráveis e  produzem sets ou dicts >>> s = abracadabra >>> {c for c in...
Tipos iteráveis embutidos  • basestring   • frozenset   • str         • list   • unicode     • set  • dict         • tuple...
Funções embutidas queconsomem iteráveis• all     • max• any     • min• filter   • reduce• iter    • sorted• len     • sum• ...
Operações com iteráveis                                       >>>   a, b, c = XYZ  • Desempacotamento                   >>...
Em Python, um iterável é...• Um objeto a partir do qual a função iter  consegue obter um iterador.• A chamada iter(x): • i...
Protocolo de sequência >>> t = Trem(4) >>> len(t) 4                       __len__ >>> t[0] vagao #1 >>> t[3]              ...
Protocolo  de sequência • implementação “informal” da interfaceclass Trem(object):    def __init__(self, num_vagoes):     ...
Interface  Sequence  • collections.Sequencefrom collections import Sequenceclass Trem(Sequence):    def __init__(self, num...
Herança de Sequence>>> t = Trem(4)>>> vagao #2 in tTrue>>> vagao #5 in tFalse>>> for i in reversed(t): print i...vagao #4v...
InterfaceIterable• Iterable provê um método  __iter__• O método __iter__ devolve  uma instância de Iterator               ...
Iterator é...• um padrão de projeto                         Design Patterns                         Gamma, Helm, Johnson &...
Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3                     @ramalhoorg
O padrãoIterator permiteacessar os itensde uma coleçãosequencialmente,isolando o clienteda implementaçãoda coleção.Head Fi...
Trem                      class Trem(object):                          def __init__(self, num_vagoes):                    ...
Em Python, um iterável é...• Um objeto a partir do qual a função iter  consegue obter um iterador.• A chamada iter(x):    ...
Iteração em C (exemplo 2) #include <stdio.h> int main(int argc, char *argv[]) {     int i;     for(i = 0; i < argc; i++)  ...
Iteração em Python (ex. 2) import sys for i, arg in enumerate(sys.argv):     print i, :, arg              $   python args2...
Iterator x generator• Gerador é uma generalização do iterador• Por definição, um objeto iterador produz itens  iterando sob...
Função               >>> def g123():geradora                     ...     yield 1                     ...     yield 2      ...
Trem c/ função geradora                      class Trem(object):                          def __init__(self, num_vagoes): ...
class Trem(object):Iterador        def __init__(self, num_vagoes):                    self.num_vagoes = num_vagoes        ...
Expressãogeradora             >>> g = (n for n in [1, 2, 3])                     >>> for i in g: print i                  ...
Trem c/ expressão geradora                      class Trem(object):                          def __init__(self, num_vagoes...
Construtores embutidosque consomem eproduzem iteráveis• dict        • reversed• enumerate   • set• frozenset   • tuple• li...
Módulo itertools• geradores (potencialmente) infinitos • count(), cycle(), repeat()• geradores que combinam vários iterávei...
Exemplo prático comfunções geradoras• Funções geradoras para desacoplar laços de  leitura e escrita em uma ferramenta para...
Exemplo prático comfunções geradoras                      @ramalhoorg
Funçõesdo script •iterMstRecords • iterIsoRecords • writeJsonArray • main	                    @ramalhoorg
Exemplo prático comfunções geradoras                      @ramalhoorg
Exemplo prático comfunções geradoras                      @ramalhoorg
Exemplo prático comfunções geradoras                      @ramalhoorg
Função main:leitura dosargumentos               @ramalhoorg
Função main: seleçãodo formato escolha dadepende geradora               de leitura                          função        ...
writeJsonArray:escreverregistrosem JSON                  @ramalhoorg
writeJsonArray:itera sobre umas dasfunções geradoras                       @ramalhoorg
iterIsoRecords:ler registros     função geradora!de arquivoISO-2709                            @ramalhoorg
iterIsoRecords                        cria um novo dict                        a cada iteração                 produz (yie...
iterMstRecords:   função geradora!ler registrosde arquivoISIS .MST                             @ramalhoorg
iterMstRecordsiterIsoRecords                    cria um novo dict                    a cada iteração             produz (y...
Exemplo prático comfunções geradoras                      @ramalhoorg
Exemplo prático comfunções geradoras                      @ramalhoorg
Luciano Ramalho                                      luciano@ramalho.org                                              @ram...
Iteraveis e geradores em Python
Upcoming SlideShare
Loading in …5
×

Iteraveis e geradores em Python

2,004 views

Published on

Se você não usa geradores, está deixando de aproveitar um recurso poderoso de Python. Partimos do pattern Iterator e mostramos seus usos práticos e suporte nativo na linguagem, incluindo funções e expressões geradoras, que permitem lidar com massas de dados muito grandes de modo eficiente e com baixo consumo de memória. Ao final, mostramos o uso prático de funções geradoras em uma ferramenta de conversão de bancos de dados.

Published in: Technology
  • Be the first to comment

Iteraveis e geradores em Python

  1. 1. Luciano Ramalho luciano@ramalho.org @ramalhoorgIteráveis, geradores & cia:o caminho pythonico
  2. 2. Luciano Ramalho luciano@ramalho.org @ramalhoorgIteráveis, geradores & cia:o caminho pythonico
  3. 3. Comparando: C e Python#include <stdio.h>int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%sn", argv[i]); return 0;} import sys for arg in sys.argv: print arg @ramalhoorg
  4. 4. Iteração em Javaclass Argumentos { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); }} $ java Argumentos alfa bravo charlie alfa bravo charlie @ramalhoorg
  5. 5. Iteração em Java ≥1.5 ano: 2004 • Enhanced for (for melhorado)class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); }} $ java Argumentos2 alfa bravo charlie alfa bravo charlie @ramalhoorg
  6. 6. ano:1990!
  7. 7. Exemplos de iteração• Iteração em Python não se limita a tipos primitivos• Exemplos • string • arquivo • Django QuerySet @ramalhoorg
  8. 8. >>> from django.db import connection>>> q = connection.queries>>> q[]>>> from municipios.models import *>>> res = Municipio.objects.all()[:5]>>> q[]>>> for m in res: print m.uf, m.nome...GO Abadia de Goiás demonstração:MG Abadia dos DouradosGO Abadiânia queryset é umMG Abaeté iterável lazyPA Abaetetuba>>> q[{time: 0.000, sql: uSELECT"municipios_municipio"."id", "municipios_municipio"."uf","municipios_municipio"."nome","municipios_municipio"."nome_ascii","municipios_municipio"."meso_regiao_id","municipios_municipio"."capital","municipios_municipio"."latitude","municipios_municipio"."longitude","municipios_municipio"."geohash" FROM "municipios_municipio"ORDER BY "municipios_municipio"."nome_ascii" ASC LIMIT 5}]
  9. 9. Em Python o comando foritera sobre... “iteráveis”• Definicão preliminar informal: • “iterável” = que pode ser iterado • assim como: “desmontável” = que pode ser desmontado• Iteráveis podem ser usados em outros contextos além do laço for @ramalhoorg
  10. 10. List comprehensionList comprehensions ● Compreensão de lista ou abrangência ● Exemplo: usar todos os elementos:• Expressões que consomem L2 = [n*10 for n in L] – iteráveis e produzem listas qualquer iterável resultado: uma lista>>> s = abracadabra>>> l = [ord(c) for c in s]>>> [ord(c) for c in s][97, 98, 114, 97, 99, 97, 100, 97, 98, 114, 97] ≈ notação matemática de conjuntos @ramalhoorg
  11. 11. Set & dict comprehensions• Expressões que consomem iteráveis e produzem sets ou dicts >>> s = abracadabra >>> {c for c in s} set([a, r, b, c, d]) >>> {c:ord(c) for c in s} {a: 97, r: 114, b: 98, c: 99, d: 100} @ramalhoorg
  12. 12. Tipos iteráveis embutidos • basestring • frozenset • str • list • unicode • set • dict • tuple • file • xrange @ramalhoorg
  13. 13. Funções embutidas queconsomem iteráveis• all • max• any • min• filter • reduce• iter • sorted• len • sum• map • zip @ramalhoorg
  14. 14. Operações com iteráveis >>> a, b, c = XYZ • Desempacotamento >>> X a de tupla >>> b Y • em atribuições >>> Z >>> c g = (n for n in [1, 2, 3]) • em chamadas de funções >>> >>> a, b, c = g a>>> def soma(a, b): 1... return a + b >>> b... 2>>> soma(1, 2) >>> c3 3>>> t = (3, 4)>>> soma(t)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: soma() takes exactly 2 arguments (1 given)>>> soma(*t) @ramalhoorg7
  15. 15. Em Python, um iterável é...• Um objeto a partir do qual a função iter consegue obter um iterador.• A chamada iter(x): • invoca x.__iter__() para obter um iterador • ou, se x.__iter__ não existe: • fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc. @ramalhoorg
  16. 16. Protocolo de sequência >>> t = Trem(4) >>> len(t) 4 __len__ >>> t[0] vagao #1 >>> t[3] __getitem__ vagao #4 >>> t[-1] vagao #4 >>> for vagao in t: ... print(vagao) __getitem__ vagao #1 vagao #2 vagao #3 vagao #4 @ramalhoorg
  17. 17. Protocolo de sequência • implementação “informal” da interfaceclass Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __len__(self): return self.num_vagoes def __getitem__(self, pos): indice = pos if pos >= 0 else self.num_vagoes + pos if 0 <= indice < self.num_vagoes: # indice 2 -> vagao #3 return vagao #%s % (indice+1) else: @ramalhoorg raise IndexError(vagao inexistente %s % pos)
  18. 18. Interface Sequence • collections.Sequencefrom collections import Sequenceclass Trem(Sequence): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __len__(self): return self.num_vagoes def __getitem__(self, pos): indice = pos if pos >= 0 else self.num_vagoes + pos if 0 <= indice < self.num_vagoes: # indice 2 -> vagao #3 return vagao #%s % (indice+1) else: @ramalhoorg raise IndexError(vagao inexistente %s % pos)
  19. 19. Herança de Sequence>>> t = Trem(4)>>> vagao #2 in tTrue>>> vagao #5 in tFalse>>> for i in reversed(t): print i...vagao #4vagao #3 from collections import Sequevagao #2vagao #1 class Trem(Sequence):>>> t.index(vagao #2) def __init__(self, num_va1 self.num_vagoes = num>>> t.index(vagao #7) def __len__(self):Traceback (most recent call last): return self.num_vagoe ... def __getitem__(self, posValueError @ramalhoorg indice = pos if pos >
  20. 20. InterfaceIterable• Iterable provê um método __iter__• O método __iter__ devolve uma instância de Iterator @ramalhoorg
  21. 21. Iterator é...• um padrão de projeto Design Patterns Gamma, Helm, Johnson & Vlissides Addison-Wesley, ISBN 0-201-63361-2 @ramalhoorg
  22. 22. Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3 @ramalhoorg
  23. 23. O padrãoIterator permiteacessar os itensde uma coleçãosequencialmente,isolando o clienteda implementaçãoda coleção.Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3 @ramalhoorg
  24. 24. Trem class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): com return IteradorTrem(self.num_vagoes) class IteradorTrem(object): iterator def __init__(self, num_vagoes): self.atual = 0 self.ultimo_vagao = num_vagoes - 1 def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return vagao #%s % (self.atual) else: iter(t) raise StopIteration() • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve IteradorTremvagao #2vagao #3 • invoca itrem.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  25. 25. Em Python, um iterável é...• Um objeto a partir do qual a função iter consegue obter um iterador.• A chamada iter(x): interface Iterable • invoca x.__iter__() para obter um iterador • ou, se x.__iter__ não existe: • fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc. protocolo de sequência @ramalhoorg
  26. 26. Iteração em C (exemplo 2) #include <stdio.h> int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%d : %sn", i, argv[i]); return 0; } $ ./args2 alfa bravo charlie 0 : ./args2 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  27. 27. Iteração em Python (ex. 2) import sys for i, arg in enumerate(sys.argv): print i, :, arg $ python args2.py alfa bravo charlie 0 : args2.py 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  28. 28. Iterator x generator• Gerador é uma generalização do iterador• Por definição, um objeto iterador produz itens iterando sobre outro objeto (alguma coleção)• Um gerador é um iterável que produz itens sem necessariamente acessar uma coleção • ele pode iterar sobre outro objeto mas também pode gerar itens por contra própria, sem qualquer dependência externa (ex. Fibonacci) @ramalhoorg
  29. 29. Função >>> def g123():geradora ... yield 1 ... yield 2 ... yield 3 ... >>> for i in g123(): print i ...• Quando invocada, 1 2 3 devolve um >>> g = g123() >>> g objeto gerador <generator object g123 at 0x10e385e10>• O objeto gerador >>> g.next() 1 >>> g.next() é um iterável 2 >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  30. 30. Trem c/ função geradora class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield vagao #%s % (i+1) iter(t) • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve geradorvagao #2vagao #3 • invoca gerador.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  31. 31. class Trem(object):Iterador def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self):clássico return IteradorTrem(self.num_vagoes) class IteradorTrem(object): def __init__(self, num_vagoes):12 linhas self.atual = 0 self.ultimo_vagao = num_vagoes - 1de código def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return vagao #%s % (self.atual) else: raise StopIteration() mesma funcionalidade e desempenho!Função class Trem(object): def __init__(self, num_vagoes):geradora self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield vagao #%s % (i+1) 3 linhas
  32. 32. Expressãogeradora >>> g = (n for n in [1, 2, 3]) >>> for i in g: print i ... 1 2 3• Quando avaliada, >>> g = (n for n in [1, 2, 3]) >>> g devolve um <generator object <genexpr> at 0x109a4deb0> objeto gerador >>> g.next() 1• O objeto gerador >>> g.next() 2 é um iterável >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  33. 33. Trem c/ expressão geradora class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): return (vagao #%s % (i+1) for i in range(self.num_vagoes)) iter(t) • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve geradorvagao #2vagao #3 • invoca gerador.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  34. 34. Construtores embutidosque consomem eproduzem iteráveis• dict • reversed• enumerate • set• frozenset • tuple• list @ramalhoorg
  35. 35. Módulo itertools• geradores (potencialmente) infinitos • count(), cycle(), repeat()• geradores que combinam vários iteráveis • chain(), tee(), izip(), imap(), product(), compress()...• geradores que selecionam ou agrupam itens: • compress(), dropwhile(), groupby(), ifilter(), islice()...• Iteradores que produzem combinações • product(), permutations(), combinations()... @ramalhoorg
  36. 36. Exemplo prático comfunções geradoras• Funções geradoras para desacoplar laços de leitura e escrita em uma ferramenta para conversão de bases de dados semi-estruturadashttps://github.com/ramalho/isis2json @ramalhoorg
  37. 37. Exemplo prático comfunções geradoras @ramalhoorg
  38. 38. Funçõesdo script •iterMstRecords • iterIsoRecords • writeJsonArray • main @ramalhoorg
  39. 39. Exemplo prático comfunções geradoras @ramalhoorg
  40. 40. Exemplo prático comfunções geradoras @ramalhoorg
  41. 41. Exemplo prático comfunções geradoras @ramalhoorg
  42. 42. Função main:leitura dosargumentos @ramalhoorg
  43. 43. Função main: seleçãodo formato escolha dadepende geradora de leitura função dode entrada formato de entrada função geradora escolhida é passada como argumento @ramalhoorg
  44. 44. writeJsonArray:escreverregistrosem JSON @ramalhoorg
  45. 45. writeJsonArray:itera sobre umas dasfunções geradoras @ramalhoorg
  46. 46. iterIsoRecords:ler registros função geradora!de arquivoISO-2709 @ramalhoorg
  47. 47. iterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  48. 48. iterMstRecords: função geradora!ler registrosde arquivoISIS .MST @ramalhoorg
  49. 49. iterMstRecordsiterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  50. 50. Exemplo prático comfunções geradoras @ramalhoorg
  51. 51. Exemplo prático comfunções geradoras @ramalhoorg
  52. 52. Luciano Ramalho luciano@ramalho.org @ramalhoorgcurso online interativo ao vivo:Objetos PythonicosPOO e padrões de projeto como devem ser em Python Pré-inscrição: pre-oopy.turing.com.br

×