gerando `C`

Propaganda
Python para quem sabe Python
Turma 1, aula 2
Iteráveis & cia.
Relembrando: iteradores em Python
●
●
Em Python iteradores são obtidos através da
função embutida iter()
A função built-in iter() obtém iteradores dos
objetos de uma destas formas:
–
–
iter(obj) procura método obj.__iter__() e o invoca
Se obj não tem método __iter__:
●
●
●
iter() tenta acessar obj[0], e se isso funcionar, cria um iterador
obj.__getitem__(0) caracteriza o velho protocolo de sequências
Se iter é invocada com 2 argumentos iter(f, s):
–
Neste caso iter() cria um iterador que invoca f() e devolve
os valores produzidos, até que f() produza o valor s
http://docs.python.org/library/collections.html#collections-abstract-base-classes
Função iter com dois argumentos
●
Se iter é invocada com 2 argumentos iter(f, s):
–
Objeto é invocado f() repetidamente até que o valor
retornado seja igual a s (a sentinela)
with
with open('mydata.txt')
open('mydata.txt') as
as fp:
fp:
for
line
in
iter(fp.readline,
for line in iter(fp.readline, ''):
''):
process_line(line)
process_line(line)
http://docs.python.org/library/functions.html#iter
from
from random
random import
import randint
randint
def
def dado():
dado():
return
return randint(1,6)
randint(1,6)
## gera
gera valores
valores ate
ate que
que um
um 66 seja
seja sorteado
sorteado
for
r
in
iter(dado,
6):
#
6
e'
o
"sentinela"
for r in iter(dado, 6): # 6 e' o "sentinela"
print
print rr
https://github.com/oturing/ppqsp/blob/master/iteraveis/demo_iter2.py
Tipos iteráveis: sequências
●
Definição do protocolo (ou interface):
●
●
Sequências imutáveis
●
●
collections.Sequence
str, unicode, tuple...
Sequências mutáveis
●
list,array.array...
http://docs.python.org/library/collections.html#collections-abstract-base-classes
Sequence
UML
●
●
Classes e métodos
abstratos em itálico
Dois exemplos de
subclasses de
Sequence:
●
str
●
tuple
List comprehension
●
Compreensão de lista ou abrangência de lista
●
Exemplo: usar todos os elementos:
–
L2 = [n*10 for n in L]
List comprehension
●
Maior legibilidade, pela clareza da intenção
●
Expressão sempre produz nova lista
>>>
>>> LL == [8,
[8, 6.9,
6.9, 6.4,
6.4, 5]
5]
>>>
>>> L2
L2 == []
[]
>>>
>>> for
for nn in
in L:
L:
...
L2.append(round(n,0))
...
L2.append(round(n,0))
...
...
>>>
>>> L2
L2
[8.0,
[8.0, 7.0,
7.0, 6.0,
6.0, 5.0]
5.0] >>>
>>> LL == [8,
[8, 6.9,
6.9, 6.4,
6.4, 5]
5]
>>>
>>> L2
L2 == [round(n,0)
[round(n,0) for
for nn in
in L]
L]
>>>
>>> L2
L2
[8.0,
[8.0, 7.0,
7.0, 6.0,
6.0, 5.0]
5.0]
List comprehension
●
Filtrar alguns elementos:
●
●
L2 = [n for n in L if n > 0]
Filtrar e processar
●
L2 = [n*10 for n in L if n > 0]
Iteráveis ansiosos x preguiçosos
●
Exemplo built-in: sorted() x reversed()
●
List comprehension x expressão geradora
>>>
>>> for
for ii in
in [letra
[letra for
for letra
letra in
in gera_letra()]:
gera_letra()]:
...
print
i
...
print i
...
>>>
for
ii in
(letra
for
letra
in
gera_letra()):
...
>>>
for
in
(letra
for
letra
in
gera_letra()):
gerando
print
i
gerando 'A'...
'A'... ...
...
print i
gerando
'B'...
...
gerando 'B'... ...
gerando
'A'...
gerando 'C'...
'C'... gerando
gerando
'A'...
AA
AA
BB
gerando
'B'...
gerando
'B'...
CC
BB
gerando
gerando 'C'...
'C'...
CC
List comp. x expressão geradora
from
from time
time import
import sleep,
sleep, strftime
strftime
def
def demora(ts=1):
demora(ts=1):
agora
agora == strftime('%H:%M:%S')
strftime('%H:%M:%S')
print
'demorando...',
print 'demorando...', agora
agora
sleep(1)
sleep(1)
return
return agora
agora
listcomp
raw_input('(tecle
raw_input('(tecle <ENTER>
<ENTER> para
para rodar
rodar oo teste
teste LISTCOMP)
LISTCOMP) ')
')
for
for tt in
in [demora()
[demora() for
for ii in
in range(3)]:
range(3)]:
print
t
print t
genexp
raw_input('(tecle
raw_input('(tecle <ENTER>
<ENTER> para
para rodar
rodar oo teste
teste GENEXP)
GENEXP) ')
')
for
for tt in
in (demora()
(demora() for
for ii in
in range(3)):
range(3)):
print
t
print t
https://github.com/oturing/ppqsp/blob/master/iteraveis/demo_genexp.py
Funções geradoras
>>>
>>> def
def xxx():
xxx():
...
yield
...
yield 'X'
'X'
...
yield
...
yield 'XX'
'XX'
...
yield
...
yield 'XXX'
'XXX'
...
...
>>>
>>> it
it == xxx()
xxx()
>>>
>>> for
for ii in
in it:
it:
...
print
...
print ii
...
...
XX
XX
XX
XXX
XXX
>>>
>>>
●
O exemplo mais simples
>>>
>>> it
it == xxx()
xxx()
>>>
>>> it
it
<generator
<generator object
object xxx
xxx at
at 0xb7840a2c>
0xb7840a2c>
>>>
it.next()
>>> it.next()
'X'
'X'
>>>
>>> it.next()
it.next()
'XX'
'XX'
>>>
>>> it.next()
it.next()
'XXX'
'XXX'
>>>
>>> it.next()
it.next()
Traceback
Traceback (most
(most recent
recent call
call last):
last):
File
"<stdin>",
line
1,
in
File "<stdin>", line 1, in <module>
<module>
StopIteration
StopIteration
Função
geradora
def
def gera_letra(ultima='C',
gera_letra(ultima='C', verboso=True):
verboso=True):
cod
cod == ord('A')
ord('A')
while
chr(cod)
while chr(cod) <=
<= ultima:
ultima:
letra
=
chr(cod)
letra = chr(cod)
if
if verboso:
verboso:
print
print 'gerando
'gerando %r...'
%r...' %% letra
letra
yield
letra
yield letra
cod
cod +=
+= 11
>>>
>>> for
for ii in
in [letra
[letra for
for letra
letra in
in gera_letra()]:
gera_letra()]:
...
print
i
...
print i
...
>>>
...
>>> for
for ii in
in (letra
(letra for
for letra
letra in
in gera_letra()):
gera_letra()):
gerando
'A'...
...
print
i
gerando 'A'...
...
print i
gerando
...
gerando 'B'...
'B'...
...
gerando
gerando
gerando 'C'...
'C'...
gerando 'A'...
'A'...
AA
AA
BB
gerando
gerando 'B'...
'B'...
CC
BB
gerando
gerando 'C'...
'C'...
CC
https://github.com/oturing/ppqsp/blob/master/iteraveis/genexp_x_listcomp.py
Funções geradoras
●
Um exemplo prático: isis2json.py
●
Objetivo dos geradores:
●
●
Desacoplar a lógica de leitura do arquivo da lógica
de gravação
Sem iteradores, o laço principal do programa teria
as duas lógicas entrelaçadas, tornando mais difícil
a manutenção e principalmente a extensão para
suportar mais formatos de entrada
https://github.com/bireme/isis2json/blob/master/isis2json.py
Funções embutidas que consomem
ou produzem iteráveis
●
Construtoras: list, dict, tuple, set, frozenset
●
●
Fábricas: range, zip, map, filter, sorted
●
●
Cria nova lista a partir de argumentos
Geradoras: enumerate, reversed, xrange*
●
●
Consome iterável, produz estrutura de dados
Cria gerador a partir de argumentos
Redutoras: all, any, sum, min, max, len, reduce**
●
Reduz iterável a um único valor
* xrange não produz um gerador ou iterador de verdade,
mas algo muito parecido
** reduce foi movida para o módulo functools no Python 3
Módulo itertools
●
Iteradores (potencialmente) infinitos
●
●
Iteradores que combinam vários iteráveis
●
●
chain(), tee(), izip(), imap(), product(), compress()...
Iteradores que selecionam ou agrupam itens:
●
●
count(), cycle(), repeat()
compress(), dropwhile(), groupby(), ifilter(), islice()...
Iteradores que produzem combinações
●
Ex: product(), permutations(), combinations()...
http://docs.python.org/library/itertools.html
Download