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

1,397
-1

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
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,397
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
40
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

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

×