SlideShare uma empresa Scribd logo
Luciano Ramalho
                      luciano@ramalho.org
                              @ramalhoorg



Iteráveis, geradores & cia:
o caminho pythonico
Luciano Ramalho
                              luciano@ramalho.org
                                      @ramalhoorg




Iteráveis, geradores & cia:
o caminho pythonico
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
Iteração em Java

class 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
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
Iteraveis e geradores em Python
ano:
1990!
Exemplos de iteração

• Iteração em Python não se limita a tipos primitivos
• Exemplos
 • string
 • arquivo
 • Django QuerySet
                                             @ramalhoorg
>>> 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 Dourados
GO Abadiânia                                   queryset é um
MG Abaeté                                      iterável lazy
PA Abaetetuba
>>> q
[{'time': '0.000', 'sql': u'SELECT
"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'}]
Em Python o comando for
itera 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
List comprehension
List 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
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
Tipos iteráveis embutidos
  • basestring   • frozenset
   • str         • list
   • unicode     • set
  • dict         • tuple
  • file          • xrange
                               @ramalhoorg
Funções embutidas que
consomem iteráveis
• all     • max
• any     • min
• filter   • reduce
• iter    • sorted
• len     • sum
• map     • zip
                        @ramalhoorg
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)                         >>>  c
3                                      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)
                                                               @ramalhoorg
7
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
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
Protocolo
  de sequência
 • implementação “informal” da interface
class 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)
Interface
  Sequence
  • collections.Sequence
from collections import Sequence

class 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)
Herança de
 Sequence
>>> t = Trem(4)
>>> 'vagao #2' in t
True
>>> 'vagao #5' in t
False
>>> for i in reversed(t): print i
...
vagao #4
vagao #3
                                     from collections import Seque
vagao #2
vagao #1
                                     class Trem(Sequence):
>>> t.index('vagao #2')
                                         def __init__(self, num_va
1
                                             self.num_vagoes = num
>>> t.index('vagao #7')
                                         def __len__(self):
Traceback (most recent call last):
                                             return self.num_vagoe
  ...
                                         def __getitem__(self, pos
ValueError                                             @ramalhoorg
                                             indice = pos if pos >
Interface
Iterable

• Iterable provê um método
  __iter__
• O método __iter__ devolve
  uma instância de Iterator



                              @ramalhoorg
Iterator é...

• um padrão de projeto

                         Design Patterns
                         Gamma, Helm, Johnson & Vlissides
                         Addison-Wesley,
                         ISBN 0-201-63361-2




                                              @ramalhoorg
Head First
Design Patterns
Poster
O'Reilly,
ISBN 0-596-10214-3




                     @ramalhoorg
O padrão
Iterator permite
acessar os itens
de uma coleção
sequencialmente,
isolando o cliente
da implementação
da coleção.
Head First
Design Patterns
Poster
O'Reilly,
ISBN 0-596-10214-3




                     @ramalhoorg
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 IteradorTrem
vagao #2
vagao #3                     •   invoca itrem.next() até que
vagao #4                         ele levante StopIteration @ramalhoorg
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
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
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
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
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
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 gerador
vagao #2
vagao #3                    •   invoca gerador.next() até que
vagao #4                        ele levante StopIteration @ramalhoorg
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 - 1
de 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
Expressão
geradora             >>> 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
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 gerador
vagao #2
vagao #3                       •   invoca gerador.next() até que
vagao #4                           ele levante StopIteration @ramalhoorg
Construtores embutidos
que consomem e
produzem iteráveis
• dict        • reversed
• enumerate   • set
• frozenset   • tuple
• list
                           @ramalhoorg
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
Exemplo prático com
funções geradoras
• Funções geradoras para desacoplar laços de
  leitura e escrita em uma ferramenta para
  conversão de bases de dados semi-estruturadas


https://github.com/ramalho/isis2json


                                           @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Funções
do script
 •iterMstRecords
 • iterIsoRecords
 • writeJsonArray
 • main	

                    @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Função main:
leitura dos
argumentos




               @ramalhoorg
Função main: seleção
do formato escolha dadepende geradora
               de leitura
                          função
                                 do
de entrada     formato de entrada




                    função geradora escolhida
                    é passada como argumento
                                      @ramalhoorg
writeJsonArray:
escrever
registros
em JSON



                  @ramalhoorg
writeJsonArray:
itera sobre umas das
funções geradoras




                       @ramalhoorg
iterIsoRecords:
ler registros     função geradora!


de arquivo
ISO-2709



                            @ramalhoorg
iterIsoRecords
                        cria um novo dict
                        a cada iteração




                 produz (yield) registro
                 na forma de um dict @ramalhoorg
iterMstRecords:   função geradora!

ler registros
de arquivo
ISIS .MST



                             @ramalhoorg
iterMstRecords
iterIsoRecords
                    cria um novo dict
                    a cada iteração




             produz (yield) registro
             na forma de um dict @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Exemplo prático com
funções geradoras




                      @ramalhoorg
Luciano Ramalho
                                      luciano@ramalho.org
                                              @ramalhoorg




curso online interativo ao vivo:
Objetos Pythonicos
POO e padrões de projeto como devem ser em Python
      Pré-inscrição: pre-oopy.turing.com.br

Mais conteúdo relacionado

PPTX
Encapsulation C++ Piller of OOP it is the important piller
PPTX
Function template
PPT
Operators in C++
PPS
Introduction to class in java
PPTX
Introduction to c++
PPTX
C++ decision making
PDF
Function in C
PPTX
Functions in c
Encapsulation C++ Piller of OOP it is the important piller
Function template
Operators in C++
Introduction to class in java
Introduction to c++
C++ decision making
Function in C
Functions in c

Mais procurados (20)

PPTX
Functions, classes & objects in c++
PPTX
Pointers,virtual functions and polymorphism cpp
PDF
Oop assignment 02
PPT
FUNCTIONS IN c++ PPT
PPT
Primitive data types in java
PPT
Generics in java
PPTX
[OOP - Lec 20,21] Inheritance
PPTX
Inline function
PPTX
11. java methods
PPTX
Data Types in C language
PDF
Data types in c++
PDF
Constructors and Destructors
PPTX
operators and control statements in c language
PPTX
Java Foundations: Methods
PPT
Polymorphism
PPT
PDF
PDF
Interfaces .net
PDF
USER DEFINED FUNCTIONS IN C MRS.SOWMYA JYOTHI.pdf
Functions, classes & objects in c++
Pointers,virtual functions and polymorphism cpp
Oop assignment 02
FUNCTIONS IN c++ PPT
Primitive data types in java
Generics in java
[OOP - Lec 20,21] Inheritance
Inline function
11. java methods
Data Types in C language
Data types in c++
Constructors and Destructors
operators and control statements in c language
Java Foundations: Methods
Polymorphism
Interfaces .net
USER DEFINED FUNCTIONS IN C MRS.SOWMYA JYOTHI.pdf
Anúncio

Semelhante a Iteraveis e geradores em Python (20)

PDF
Iteraveis e geradores
PDF
Python: Iteraveis, geradores etc
PDF
Orientação a objetos em Python (compacto)
PDF
Objetos Pythonicos - compacto
KEY
Introdução à Linguagem de programação Python
PDF
Python para quem sabe Python (aula 2)
PDF
Iteráveis e geradores (versão RuPy)
PPTX
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
PDF
Introdução à Linguagem Ruby
PDF
Introdução a linguagem Python
PDF
TDC2016SP - Trilha Node.Js
PDF
Python Class
PDF
Ruby on rails gds 2011
PDF
O que é que o Java não tem?
PDF
Ruby - Criando código para máquinas e humanos
PDF
Palestra python
PDF
O que mudou no Ruby 1.9
PDF
PDF
Unidade7 1
Iteraveis e geradores
Python: Iteraveis, geradores etc
Orientação a objetos em Python (compacto)
Objetos Pythonicos - compacto
Introdução à Linguagem de programação Python
Python para quem sabe Python (aula 2)
Iteráveis e geradores (versão RuPy)
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
Introdução à Linguagem Ruby
Introdução a linguagem Python
TDC2016SP - Trilha Node.Js
Python Class
Ruby on rails gds 2011
O que é que o Java não tem?
Ruby - Criando código para máquinas e humanos
Palestra python
O que mudou no Ruby 1.9
Unidade7 1
Anúncio

Mais de Luciano Ramalho (20)

PDF
Wiki-wiki S/A
PDF
Mongodb: agregação
PDF
Encapsulamento com descritores
PDF
Arduino: hardware hacking & coding dojo
PDF
Encapsulamento com Descritores em Python
PDF
Dojo com Processing
PDF
Dojo com Arduino
PDF
Open Library no Mongodb
PDF
Jython no JavaOne Latin America 2011
PDF
OO em Python sem sotaque
KEY
Modelos ricos
KEY
Python, a arma secreta do Google
KEY
Ensinando OO com Python
KEY
Alex Martelli's Python Design Patterns
PDF
Dspace em 5 minutos
PDF
JavaScript agora é sério (TDC 2011)
PDF
JavaScript agora é sério (FISL 2011)
PDF
Wiki sa-v2
PDF
JavaScript: agora é sério
PDF
Porque bibliotecários usam bancos de dados esquisitos
Wiki-wiki S/A
Mongodb: agregação
Encapsulamento com descritores
Arduino: hardware hacking & coding dojo
Encapsulamento com Descritores em Python
Dojo com Processing
Dojo com Arduino
Open Library no Mongodb
Jython no JavaOne Latin America 2011
OO em Python sem sotaque
Modelos ricos
Python, a arma secreta do Google
Ensinando OO com Python
Alex Martelli's Python Design Patterns
Dspace em 5 minutos
JavaScript agora é sério (TDC 2011)
JavaScript agora é sério (FISL 2011)
Wiki sa-v2
JavaScript: agora é sério
Porque bibliotecários usam bancos de dados esquisitos

Último (19)

PDF
Apple Pippin Uma breve introdução. - David Glotz
PDF
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
PDF
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
PDF
Aula04-Academia Heri- Tecnologia Geral 2025
PDF
Processos na gestão de transportes, TM100 Col18
PDF
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
PDF
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
PDF
COBITxITIL-Entenda as diferença em uso governança TI
PPTX
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
PPTX
Aula 18 - Manipulacao De Arquivos python
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
PDF
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
PPTX
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
PPTX
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
PDF
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
PPTX
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
PDF
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
PPTX
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
PDF
Custos e liquidação no SAP Transportation Management, TM130 Col18
Apple Pippin Uma breve introdução. - David Glotz
Fullfilment AI - Forum ecommerce 2025 // Distrito e Total Express
Mergulho profundo técnico para gestão de transportes no SAP S/4HANA, S4TM6 Col14
Aula04-Academia Heri- Tecnologia Geral 2025
Processos na gestão de transportes, TM100 Col18
20250805_ServiceNow e a Arquitetura Orientada a Serviços (SOA) A Base para Ap...
Otimizador de planejamento e execução no SAP Transportation Management, TM120...
COBITxITIL-Entenda as diferença em uso governança TI
Como-se-implementa-um-softwareeeeeeeeeeeeeeeeeeeeeeeee.pptx
Aula 18 - Manipulacao De Arquivos python
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
Fundamentos de gerenciamento de ordens e planejamento no SAP TransportationMa...
Gestao-de-Bugs-em-Software-Introducao.pptxxxxxxxx
BANCO DE DADOS - AULAS INICIAIS-sgbd.pptx
Custos e faturamento no SAP S/4HANA Transportation Management, S4TM3 Col26
Aula16ManipulaçãoDadosssssssssssssssssssssssssssss
Gestão de transportes básica no SAP S/4HANA, S4611 Col20
Programação - Linguagem C - Variáveis, Palavras Reservadas, tipos de dados, c...
Custos e liquidação no SAP Transportation Management, TM130 Col18

Iteraveis e geradores em Python

  • 1. Luciano Ramalho luciano@ramalho.org @ramalhoorg Iteráveis, geradores & cia: o caminho pythonico
  • 2. Luciano Ramalho luciano@ramalho.org @ramalhoorg Iteráveis, geradores & cia: o caminho pythonico
  • 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. Iteração em Java class 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. 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
  • 8. Exemplos de iteração • Iteração em Python não se limita a tipos primitivos • Exemplos • string • arquivo • Django QuerySet @ramalhoorg
  • 9. >>> 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 Dourados GO Abadiânia queryset é um MG Abaeté iterável lazy PA Abaetetuba >>> q [{'time': '0.000', 'sql': u'SELECT "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'}]
  • 10. Em Python o comando for itera 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
  • 11. List comprehension List 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
  • 12. 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
  • 13. Tipos iteráveis embutidos • basestring • frozenset • str • list • unicode • set • dict • tuple • file • xrange @ramalhoorg
  • 14. Funções embutidas que consomem iteráveis • all • max • any • min • filter • reduce • iter • sorted • len • sum • map • zip @ramalhoorg
  • 15. 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) >>> c 3 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) @ramalhoorg 7
  • 16. 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
  • 17. 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
  • 18. Protocolo de sequência • implementação “informal” da interface class 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)
  • 19. Interface Sequence • collections.Sequence from collections import Sequence class 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)
  • 20. Herança de Sequence >>> t = Trem(4) >>> 'vagao #2' in t True >>> 'vagao #5' in t False >>> for i in reversed(t): print i ... vagao #4 vagao #3 from collections import Seque vagao #2 vagao #1 class Trem(Sequence): >>> t.index('vagao #2') def __init__(self, num_va 1 self.num_vagoes = num >>> t.index('vagao #7') def __len__(self): Traceback (most recent call last): return self.num_vagoe ... def __getitem__(self, pos ValueError @ramalhoorg indice = pos if pos >
  • 21. Interface Iterable • Iterable provê um método __iter__ • O método __iter__ devolve uma instância de Iterator @ramalhoorg
  • 22. Iterator é... • um padrão de projeto Design Patterns Gamma, Helm, Johnson & Vlissides Addison-Wesley, ISBN 0-201-63361-2 @ramalhoorg
  • 24. O padrão Iterator permite acessar os itens de uma coleção sequencialmente, isolando o cliente da implementação da coleção. Head First Design Patterns Poster O'Reilly, ISBN 0-596-10214-3 @ramalhoorg
  • 25. 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 IteradorTrem vagao #2 vagao #3 • invoca itrem.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 26. 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
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. 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
  • 31. 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 gerador vagao #2 vagao #3 • invoca gerador.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 32. 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 - 1 de 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
  • 33. Expressão geradora >>> 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
  • 34. 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 gerador vagao #2 vagao #3 • invoca gerador.next() até que vagao #4 ele levante StopIteration @ramalhoorg
  • 35. Construtores embutidos que consomem e produzem iteráveis • dict • reversed • enumerate • set • frozenset • tuple • list @ramalhoorg
  • 36. 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
  • 37. Exemplo prático com funções geradoras • Funções geradoras para desacoplar laços de leitura e escrita em uma ferramenta para conversão de bases de dados semi-estruturadas https://github.com/ramalho/isis2json @ramalhoorg
  • 38. Exemplo prático com funções geradoras @ramalhoorg
  • 39. Funções do script •iterMstRecords • iterIsoRecords • writeJsonArray • main @ramalhoorg
  • 40. Exemplo prático com funções geradoras @ramalhoorg
  • 41. Exemplo prático com funções geradoras @ramalhoorg
  • 42. Exemplo prático com funções geradoras @ramalhoorg
  • 44. Função main: seleção do formato escolha dadepende geradora de leitura função do de entrada formato de entrada função geradora escolhida é passada como argumento @ramalhoorg
  • 46. writeJsonArray: itera sobre umas das funções geradoras @ramalhoorg
  • 47. iterIsoRecords: ler registros função geradora! de arquivo ISO-2709 @ramalhoorg
  • 48. iterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  • 49. iterMstRecords: função geradora! ler registros de arquivo ISIS .MST @ramalhoorg
  • 50. iterMstRecords iterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  • 51. Exemplo prático com funções geradoras @ramalhoorg
  • 52. Exemplo prático com funções geradoras @ramalhoorg
  • 53. Luciano Ramalho luciano@ramalho.org @ramalhoorg curso online interativo ao vivo: Objetos Pythonicos POO e padrões de projeto como devem ser em Python Pré-inscrição: pre-oopy.turing.com.br